立即行动后单选按钮被重置(转换器和ui:重复涉及神秘)

时间:2012-10-23 15:43:39

标签: jsf immediate-attribute

我遇到的情况是,只要视图从立即操作返回,一组单选按钮就会重置为非选择状态,尽管正确处理了实际值。刷新视图还会显示正确的值。奇怪的是,只有当组件使用转换器并且不在ui:repeat内时才会发生这种行为。我将其缩小到以下示例:

JSF Page

<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>

Backing Bean

@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”)
  • 提交按钮+输出以测试值是否设置正确。
  • 具有一些立即操作的按钮,除了更改JSF生命周期之外别无其他操作。

有了这个,人们可以玩并观察以下内容:

  • 每当页面从立即操作返回时,转换器外部 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

1 个答案:

答案 0 :(得分:0)

我仍然没有真正理解它为什么会这样,但我找到了两个解决方案。

1)doNothing()方法不符合spec,后者要求签名必须与java.lang.Object action()匹配

如果我正确添加返回值以返回同一页面(通过文件名“test.xhtml”或通过faces-config中的outcomenavigation-rule),一切正常细

2)如果我在按钮上添加f:ajax来执行并重新渲染部分页面,一切都很顺利。我玩了一下,看起来页面的哪个部分被执行/重新渲染似乎并不重要(除了应用值等的正常效果)。

我仍然对最初相当随机的行为感到困惑(以及ui:重复和转换器如何影响它)。似乎我对JSF如何在没有显式导航的情况下返回页面的理解是不完整的。这也适用于通过FacesContext#renderResponse验证失败后返回。任何帮助表示感谢(如果合适,我也可以打开一个新问题然后编辑这个答案)