我遇到的情况是,只要视图从立即操作返回,一组单选按钮就会重置为非选择状态,尽管正确处理了实际值。刷新视图还会显示正确的值。奇怪的是,只有当组件使用转换器并且不在ui:repeat
内时才会发生这种行为。我将其缩小到以下示例:
<ui:repeat value="#{bean.stringList}" var="item" varStatus="iteration">
#{item}
<h:selectOneRadio value="#{bean.boolValue}" rendered="#{iteration.last}">
<f:selectItems value="#{bean.boolItemList}" />
<f:converter converterId="testConverter" />
</h:selectOneRadio><br /><br />
</ui:repeat>
<hr />
<h:selectOneRadio value="#{bean.stringValue}">
<f:selectItems value="#{bean.stringItemList}" />
</h:selectOneRadio>
<h:selectOneRadio value="#{bean.boolValue}">
<f:selectItems value="#{bean.boolItemList}" />
<f:converter converterId="testConverter" />
</h:selectOneRadio>
<p>
<h:commandButton value="Submit" type="submit" />
<h:commandButton value="Do nothing, but immediate!" immediate="true" action="#{bean.doNothing}" />
</p>
<p>boolValue is: #{bean.boolValue}</p>
@ManagedBean(name = "bean")
@SessionScoped
public class Bean {
private List<String> stringList;
private List<SelectItem> stringItemList;
private List<SelectItem> boolItemList;
private boolean boolValue;
private String stringValue;
private int removeParam;
public Bean() {
stringList = new ArrayList<String>();
stringList.add("Test Item One");
stringList.add("Test Item Two");
stringItemList = new ArrayList<SelectItem>();
stringItemList.add(new SelectItem("1", "Option One"));
stringItemList.add(new SelectItem("2", "Option Two"));
boolItemList = new ArrayList<SelectItem>();
boolItemList.add(new SelectItem(Boolean.TRUE, "This is real"));
boolItemList.add(new SelectItem(Boolean.FALSE, "This is not real"));
}
// + getters and setters
public void doNothing(){
}
}
@FacesConverter("testConverter")
public class TestConverter implements Converter {
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value)
{
if (value!= null) {
if (value.equals("real"))
{
return Boolean.TRUE;
}
}
return Boolean.FALSE;
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
boolean check = (Boolean) value;
if (check) return "real";
else return "unreal";
}
}
所以我们有:
SelectItem(String, String)
的辅助bean列表构建的一组单选按钮,保存到String。无需转换器。SelectItem(boolean, String)
的辅助bean列表构建的一组单选按钮,保存为布尔值。提供转换器将布尔值映射到某些单词(“real”/“unreal”) - 只是为了替换标准转换器(“true”/“false”)有了这个,人们可以玩并观察以下内容:
ui:repeat
的无线电都不显示任何值,这意味着:未选择无线电ui:repeat
内的相同的无线电组工作正常,没有转换器的那个针对更好的知识进行测试我检查了放在<c:foreach>
而不是ui:repeat
内的转换器无线电显示相同的错误(这是我预期的,因为它只是构建树和然后消失)并且将一些标准转换器附加到字符串无线电并不会使它们断开。关于BalusC的评论,将bean更改为ViewScoped不会影响问题 - 只有这样,刷新才会为您提供一个空白的默认初始化页面。
在这里,我知道了。我真的没有看到如何进一步减少这个或为什么它的行为像这样。那么......好吧......任何人的想法?
我从服务器上获得的规格:Mojarra JSF API实现2.0.5-FCS,JSF 2.0和Facelets,Server是一个Weblogic 11g 10.3
答案 0 :(得分:0)
我仍然没有真正理解它为什么会这样,但我找到了两个解决方案。
1)doNothing()
方法不符合spec,后者要求签名必须与java.lang.Object action()
匹配
如果我正确添加返回值以返回同一页面(通过文件名“test.xhtml”或通过faces-config中的outcome
和navigation-rule
),一切正常细
2)如果我在按钮上添加f:ajax
来执行并重新渲染部分页面,一切都很顺利。我玩了一下,看起来页面的哪个部分被执行/重新渲染似乎并不重要(除了应用值等的正常效果)。
我仍然对最初相当随机的行为感到困惑(以及ui:重复和转换器如何影响它)。似乎我对JSF如何在没有显式导航的情况下返回页面的理解是不完整的。这也适用于通过FacesContext#renderResponse
验证失败后返回。任何帮助表示感谢(如果合适,我也可以打开一个新问题然后编辑这个答案)