我的JSF页面中有一个简单的Form,如下所示:
<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",
}));
}
}
观察:
getCities
和setCities
方法的入口和出口添加了日志记录。在刷新JSF页面期间,调用getCities
方法。但是,提交时,setCities
永远不会被调用。<h:messages/>
问题似乎与commandButton/commandLink/ajax action/listener method not invoked or input value not set/updated接受的答案问题#3类似,但是我没有<p:selectCheckboxMenu>
的明显转换问题。根据文档,它应该能够完美地处理List<String>
。
因此,除了解决明显的问题之外,我们如何确保与此相关的任何错误都可见,而不是让这种无声的失败?
简而言之,<f:viewParam>
does not yet support list of values。
cities
财产的签名是List<String>
。
请注意,当我们尝试传递cities
的参数(将?cities=Dallas
附加到请求URL的末尾)时,我们突然在<h:messages/>
中获得了适当的转换错误,说明:
'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风格的提交过程中需要设置<f:viewParam>
?
要解决这个问题,您可以提供<f:converter>
,或提供额外的getter / setter来处理基于String设置/获取Array或List类型。
选择快速解决方案,我们可以更改<f:viewParam>
如下:
<f:viewParam name="cities" value="#{myBean.citiesCsv}" />
对于支持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转换。
相关文章