【问题标题】:UIInput set methods not called on submitting JSF Page with <f:viewParams>使用 <f:viewParams> 提交 JSF 页面时未调用 UIInput 设置方法
【发布时间】:2019-02-20 18:53:35
【问题描述】:

我的 JSF 页面中有一个简单的表单,如下所示:

<html 
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://xmlns.jcp.org/jsf/html"
  xmlns:f="http://java.sun.com/jsf/core"
>
  <f:view>
    <h:head>
      <f:metadata>
        <f:viewParam name="cities" value="#{myBean.cities}" />
      </f:metadata>
    </h:head>
    <h:body>
      <h:form>
        <h:messages id="messages" />
        <h:selectManyCheckbox value="#{myBean.cities}" label="Select City" >
          <f:selectItems value="#{myBean.allCities}" />
        </p:selectManyCheckbox>
        <h:commandButton value="Submit">
          <f:ajax execute="@form" render="output"/>
        </h:commandButton>
      </h:form>
      <h:panelGroup id="output">
        Number of Selected Cities: #{myBean.cities.size()}
      </h:panelGroup>
    </h:body>
  </f:view>
</html>

匹配的支持bean:

使用以下 bean 方法:

@Named
@RequestScoped
public class MyBean {
  private List<String> cities = new ArrayList<>();

  public List<String> getCities() {
    return cities;
  }

  public void setCities(List<String> cities) {
    this.cities = cities;
  }

  public List<String> getAllCities() {
    return new ArrayList<>(Arrays.asList(new String [] {
      "Los Angeles",
      "St. Louis",
      "San Francisco",
      "Dallas",
      }));
  }
}

观察:

  1. 我在getCitiessetCities 方法的入口和出口中添加了日志记录。在刷新 JSF 页面期间,将调用 getCities 方法。但是,在提交时,setCities 永远不会被调用。
  2. 我在控制台日志中没有看到任何错误或异常(javax.faces.PROJECT_STAGE 在 web.xml 中设置为 DEVELOPMENT)。
  3. 没有错误被传递给&lt;h:messages/&gt;
  4. 不会为任何表单输入字段调用 set 方法。该页面的行为“奇怪”。

这个问题似乎与来自commandButton/commandLink/ajax action/listener method not invoked or input value not set/updated 的已接受答案的问题#3 相似,但是对于&lt;p:selectCheckboxMenu&gt;,我没有明显的转换问题。根据文档,它应该能够完美处理List&lt;String&gt;

所以除了解决明显的问题,我们如何确保与此相关的任何错误都可见,而不是出现这种无声的故障类型?

【问题讨论】:

  • 所以只是存在 f:viewParam - 指向与输入相同的 Collection 类型 bean 属性 - 静默阻止用户输入提交?
  • 是的。它在第一次渲染时不会失败(当没有提供 GET 参数时),但在提交(ajax)表单时它确实会失败。

标签: jsf


【解决方案1】:

简而言之,&lt;f:viewParam&gt; does not yet support list of values

cities 属性的签名是List&lt;String&gt;

请注意,当我们尝试传递 cities 的参数时(将 ?cities=Dallas 附加到请求 URL 的末尾),我们会在 &lt;h:messages/&gt; 中突然收到一个适当的转换错误,说明:

“null Converter”的转换错误设置值“Dallas”。

根据引用的帖子,我们还应该包含 ajax 更新的消息:

    <h:commandButton value="Submit">
      <f:ajax execute="@form" render="output"/>
      <f:ajax execute="@form" render="messages"/>
    </h:commandButton>

当遵循这个时,不是在第一次访问期间,而是至少在提交期间我们会得到一个适当的错误:

“null Converter”的转换错误设置值“[]”。

我不确定为什么需要在 ajax 样式提交期间设置 &lt;f:viewParam&gt;

要解决此问题,您可以提供&lt;f:converter&gt;,或提供额外的 getter/setter 来处理基于字符串设置/获取 Array 或 List 类型。

选择一个快速的解决方案,我们可以将&lt;f:viewParam&gt; 更改如下:

<f:viewParam name="cities" value="#{myBean.citiesCsv}" />

而对于 backing bean,我们添加以下方法:

  public void setCitiesCsv(String csv) {
    if (csv.isEmpty()) {
      cities = new ArrayList<>();
    } else {
      cities = 
         Stream.of(csv.split(","))
           .collect(Collectors.toCollection(ArrayList<String>::new));
    }
  }

为了反复进​​行此类努力,我们可能应该考虑使用适当的转换器,如果它适合我​​们的目的,我们可以为简单的 CSV 转换自定义构建。

相关帖子

【讨论】:

  • 我不知道你的广泛回答是如何回答这个问题的。
  • 开发人员应该学会制作minimal reproducible example,不要怀疑任何事情。怀疑是针对阴谋论者的,而不是开发商。开发人员通过调试来缩小问题范围,其中创建minimal reproducible example 是一个更大的部分。当然stackoverflow.com/questions/2118656 中的#3 也没有帮助?
  • 我并不是说它没有帮助,只是关系不是那么清楚。我怀疑其他有类似问题的人在阅读您的问题时会继续阅读。我认为他们可能会停下来,认为他们的问题是无关的。如果您更加强调“更大”的事情(不是整个页面,而是声明制作minimal reproducible example 将是正确的方法,并首先说明问题在于没有发现转换错误在 viewparam 作为一个简短的答案,然后添加一个较长的答案的第二部分,这可能会有所帮助。
  • 我可能是你遇到的是一个全新的案例,它本身就有效。很高兴知道h:messages 没有帮助。然后我们需要在 stackoverflow(或其他搜索引擎)中找出是否有办法在 viewparam 中捕获这些转换错误。尝试在开发模式下运行? (如链接/答案中所述)。你的 JSF 版本和实现是什么?并检查stackoverflow.com/questions/26755749 有助于防止我认为将来发生这种情况。
  • 我在stackoverflow.com/questions/44419951/… 中找到了我的答案,建议尝试使用showcase.omnifaces.org/cdi/Param 中的@Param 注释。如果操作正确,它可以同时使用多值参数和转换器。是的,您在视图中看不到它需要一个参数,但它可能需要研究,因为您可以使用普通的 getter/setter 比(带有一些注释或...
猜你喜欢
  • 1970-01-01
  • 2013-04-06
  • 2012-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多