我遇到 JSF CommandButton 操作未被调用的问题。 我有一个托管 bean roleController,如
@ManagedBean(name = "roleController")
@RequestScoped
public class RoleController {
public Role getSelectedRole() {
return selectedRole;
}
public void updateSelectedRole() {
System.out.println(selectedRole.getRole());
}
在我的 .jsf 文件中,我尝试编辑 h:commandButton 上的调用 updateSelectedRole 操作,但它似乎不起作用。我尝试将方法名称更改为不正确的方法名称,并且没有抛出异常 - 但是当我对其他形式执行相同操作时,会抛出异常 - 所以很可能该操作甚至没有被调用。
<h:panelGroup rendered="${param.action == 'edit'}">
<h:form>
<ol>
<li>
<label for="ID">
<h:outputText value="#{msg.roleEditID}" />
</label>
<h:inputText readonly="true"
value="#{roleController.selectedRole.id}" />
</li>
<li>
<label for="Role">
<h:outputText value="#{msg.roleEditRole}" />
</label>
<h:inputText value="#{roleController.selectedRole.role}" />
</li>
<li>
<h:commandButton value="#{msg.buttonUpdate}"
action="#{roleController.updateSelectedRole()}"/>
</li>
</ol>
</h:form>
</h:panelGroup>
我发现这可能是嵌套表单造成的,但本例中并非如此。难道这个问题的根源是我的导航规则?
<navigation-rule>
<from-view-id>/admin/roles.xhtml</from-view-id>
<navigation-case>
<to-view-id>/admin/roles.xhtml</to-view-id>
<from-outcome>true</from-outcome>
<redirect>
<view-param>
<name>action</name>
<value>edit</value>
</view-param>
</redirect>
</navigation-case>
</navigation-rule>
该操作未被调用,因为命令按钮组件未渲染。
在处理表单提交期间,将重新评估父面板组组件上的
rendered="${param.action == 'edit'}"
,以防止请求被篡改/黑客攻击。想象一下,您在某处有一个 rendered="#{user.isAdmin}"
,那么您显然不希望非管理员用户通过简单地篡改 HTTP 请求来触发此操作。
由于您显然没有在回发中保留该请求参数(至少,代码中没有任何内容证明其他情况),因此它的计算结果为
false
。因此,父面板组组件(包括其所有子组件)不会被渲染。
您只需确保命令按钮及其所有父组件的
rendered
属性在表单提交期间计算结果为 true
。在这种特殊情况下,您可以通过在命令按钮本身中包含 <f:param>
来保留请求参数来实现此目的。
<h:commandButton ...>
<f:param name="action" value="#{param.action}" />
</h:commandButton>
与具体问题无关,建议禁止在 JSF 中使用
${}
,否则会导致不必要的混乱和问题。只要始终坚持#{}
即可。
<h:commandButton value="#{msg.buttonUpdate}"
action="#{roleController.updateSelectedRole()}"/>
更改为
<h:commandButton value="#{msg.buttonUpdate}"
action="#{roleController.updateSelectedRole}"/>
您的行动号召不需要括号。
public void updateSelectedRole() {
System.out.println(selectedRole.getRole());
}
并且方法action方法需要返回一个字符串
public String updateSelectedRole() {
System.out.println(selectedRole.getRole());
return "true";
}
来自客户端的请求必须封装在 HTTP 表单中
此顺序更改在我的情况下有效:
<h:form>
<h:panelGroup rendered="${param.action == 'edit'}">
.
.
.
</h:panelGroup>
</h:form>