我偶然发现了一个奇怪的问题,我试图解决一整天。我未能在下面的简单示例中重现它,但也许有人可以给我一些想法。
视图代码:
<h:selectOneMenu id="color"
value="#{testModel.color}" required="true"
converter="#{colorConverter}">
<f:selectItems id="colorList"
value="#{testModel.colorList}"
var="colorVar" itemLabel="#{colorVar.name}" itemValue="#{colorVar}"/>
</h:selectOneMenu>
会话范围模型:
@javax.inject.Named
@javax.enterprise.context.SessionScoped
public class TestModel implements Serializable {
private Color color;
//color getters and setters
private static final List<Color> colorList;
static {
// in real example I initialize this list from database
colorList = new ArrayList<Color>();
colorList.add(Color.getRedColor());
colorList.add(Color.getGreenColor());
colorList.add(Color.getBlueColor());
}
public List<Color> getColorList() {
return colorList;
}
public String save() {
//doing some stuff
// stay on the same page
return null;
}
}
颜色转换器:
@Named
@ApplicationScoped
public class ColorConverter implements Converter {
@Override
public Object getAsObject(FacesContext context, UIComponent component,
String value) {
return value != null ? Color.valueOf(value) : null;
}
@Override
public String getAsString(FacesContext context, UIComponent component,
Object value) {
if (value instanceof Color) {
return ((Color) value).getName();
}
return null;
}
}
这个简单的例子工作正常。但在现实生活中,Color
对象是DTO
从域对象映射而来的。我尝试只初始化一次颜色列表,并在转换器中使用它的项目,以便ColorConverter#getAsObject
从颜色列表中返回一个项目。
所以,问题是这样的。在该Update Model
阶段中,所选项目被正确转换并设置为模型。然后在该Invoke Application
阶段TestModel#save
调用返回 null 的方法,这意味着应该重新显示同一页面。但是页面重新加载后,列表会再次重新初始化,并且选定的项目会被重置。我希望它显示保存在模型中的选定项目。