ajax - <h :selectManyCheckbox> with validation on ajax update when INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL is active 的 ClassCastException

标签 ajax jsf jsf-2.3 selectmanycheckbox

我有一个 <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)。我在做什么:

screenshot of UI

  1. 输入一些文本并离开框:ajax 更新运行,在模型中成功设置值
  2. 我按下提交:弹出空复选框的验证错误
  3. 我修改输入中的文本并保留框: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/

相关文章:

javascript - 使用数据在angularjs中发送ajax请求

html - 将带有 HTML 代码的字符串注入(inject)并解释为 JSF 页面的组件

java - JSF 登录过滤器

jsf - Primefaces - 验证失败时切换所有就地

jsf - <f :ajax render ="@none" execute ="@this"> and reducing submitted post data size in large form

jsf - 将 faces-config.xml 从 2.2 更改为 2.3 会导致 javax.el.PropertyNotFoundException : Target Unreachable, 标识符 'bean' 解析为 null

jsf - primefaces 和 JSF 2.3 javascript 错误无法读取 null 的属性 'error'

php - 如何使用 php 和 html 根据组合框选择的变化自动更改输入文本框的值

javascript - Jquery Ajax POST 不发送所有数据

javascript - MVC/AJAX 将数据发送到 Controller 并在同一 View 中加载响应