我有一个 <h:selectManyCheckbox>
需要验证。如果我提交表单,当没有选择任何内容时我会收到验证错误。到目前为止,这是预期的。但是,如果我在复选框上执行 ajax 更新,我会得到 ClassCastException
。 .但前提是空值被视为 null
.
所以,我有以下设置。在web.xml
我设置
<context-param>
<param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
<param-value>true</param-value>
</context-param>
然后我有一个像这样的 xhtml 页面:
<h:form id="main">
<h:selectManyCheckbox id="value" value="#{testcb.selected}" required="true" requiredMessage="Select at least one entry">
<f:selectItems value="#{testcb.available}"/>
</h:selectManyCheckbox>
<div><h:message for="value" style="color:red;"/></div>
<h:outputLabel for="checkit" value="Enter some text: "/>
<h:inputText id="checkit" value="#{testcb.text}">
<f:ajax event="change" execute="@this" render=":main:value"/>
</h:inputText>
<div><h:commandButton type="submit" value="Submit" action="#{testcb.action}"/></div>
</h:form>
还有这个支持 bean:
@Named("testcb")
@SessionScoped
public class TestCBBean implements Serializable {
private final Set<TestValue> available = EnumSet.allOf(TestValue.class);
private final Set<TestValue> selected = EnumSet.noneOf(TestValue.class);
private String text;
public void action() {}
public Set<TestValue> getAvailable() { return available; }
public void setAvailable(Set<TestValue> available) {
this.available.clear();
this.available.addAll(available);
}
public Set<TestValue> getSelected() { return selected; }
public void setSelected(Set<TestValue> selected) {
this.selected.clear();
this.selected.addAll(selected);
}
public String getText() { return text; }
public void setText(String text) { this.text = text; }
}
还有这个enum
:
public enum TestValue { ONE, TWO, THREE }
我在 Wildfly 26.0.1-Final (JavaEE 8) 中运行它。但这也发生在旧版本中(如 Wildfly 15)。我在做什么:
- 输入一些文本并离开框:ajax 更新运行,在模型中成功设置值
- 我按下提交:弹出空复选框的验证错误
- 我修改输入中的文本并保留框:ajax 更新导致以下异常:
java.lang.ClassCastException: class java.lang.String cannot be cast to class [Ljava.lang.Object; (java.lang.String and [Ljava.lang.Object; are in module java.base of loader 'bootstrap')
com.sun.jsf-impl@2.3.17.SP01//com.sun.faces.renderkit.html_basic.MenuRenderer.getSubmittedSelectedValues(MenuRenderer.java:508)
com.sun.jsf-impl@2.3.17.SP01//com.sun.faces.renderkit.html_basic.SelectManyCheckboxListRenderer.encodeEnd(SelectManyCheckboxListRenderer.java:89)
javax.faces.api@3.1.0.SP01//javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:600)
javax.faces.api@3.1.0.SP01//javax.faces.component.UIComponent.encodeAll(UIComponent.java:1655)
com.sun.jsf-impl@2.3.17.SP01//com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:628)
com.sun.jsf-impl@2.3.17.SP01//com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:159)
javax.faces.api@3.1.0.SP01//javax.faces.component.UIComponent.visitTree(UIComponent.java:1457)
javax.faces.api@3.1.0.SP01//javax.faces.component.UIComponent.visitTree(UIComponent.java:1469)
javax.faces.api@3.1.0.SP01//javax.faces.component.UIForm.visitTree(UIForm.java:355)
在 ajax 更新中,未提交复选框。但它们似乎包含一个空字符串作为之前验证步骤的提交值。
将上下文参数设置为 false
时这有效。但我想保留它 true
.有什么想法可以解决这个问题吗?
最佳答案
转载。这确实是 Mojarra 中的一个错误。
归结为UIInput
父类(super class)中的以下方法...
@Override
public Object getSubmittedValue() {
if (submittedValue == null && !isValid() && considerEmptyStringNull(FacesContext.getCurrentInstance())) {
return "";
} else {
return submittedValue;
}
}
... 未在 UISelectMany
父类(super class)中以返回 new String[0]
而不是 的方式被覆盖” “
。这是实现过程中的疏忽 Faces issue 671 .
我已经在 Mojarra issue 5081 中修复了它.
与此同时,在升级到包含修复程序的 Mojarra 版本之前,您可以通过复制粘贴整个 source code 来临时解决它。将 UISelectMany
文件添加到您的项目中,同时维护包并向其中添加以下方法:
@Override
public Object getSubmittedValue() {
Object submittedValue = super.getSubmittedValue();
return "".equals(submittedValue) ? new String[0] : submittedValue;
}
关于ajax - <h :selectManyCheckbox> with validation on ajax update when INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL is active 的 ClassCastException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71693174/