Den*_*sGL 8 jsf cdi jsf-2 jboss-weld
我面临以下问题:在一个页面中,我列出了我的应用程序的所有用户,并为每个用户都有一个"编辑"按钮,这是一个"GET"链接?id=<userid>.
编辑页面具有<f:viewParam name="id" value="#{editUserBean.id}"/>元数据.
如果我输入了一些输入错误并提交(我使用CDI Weld Bean验证),页面会再次显示,但我丢失?id=...了URL,因此丢失了我正在编辑的用户的用户ID.
我看过JSF验证错误中描述的类似问题,丢失了值,但是带有inputhidden的解决方案(或更糟糕的是,使用tomahawk,看起来有点过分)需要大量的uggly代码.
我尝试用CDI添加一个"对话",它正在工作,但它看起来对我来说太过分了.
在验证错误的情况下,JSF中是否存在一个简单的解决方案来保留视图参数?
[我的环境:Tomcat7 + MyFaces 2.1.0 + Hibernate Validator 4.2.0 + CDI(Weld)1.1.2]
有趣的案例.对于每个人来说,以下最小代码重现了这一点:
的facelet:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
>
<f:metadata>
<f:viewParam id="id" name="id" value="#{viewParamBean.id}"/>
</f:metadata>
<h:body>
<h:messages />
#{viewParamBean.id} <br/>
<h:form>
<h:inputText value="#{viewParamBean.text}" >
<f:validateLength minimum="2"/>
</h:inputText>
<h:commandButton value="test" action="#{viewParamBean.actionMethod}"/>
</h:form>
</h:body>
</html>
Run Code Online (Sandbox Code Playgroud)
豆:
@ManagedBean
@RequestScoped
public class ViewParamBean {
private long id;
private String text;
public void actionMethod() {
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
Run Code Online (Sandbox Code Playgroud)
如果用viewparam.xhtml?id=12它调用Facelet,它将显示在12屏幕上.如果你输入了一些有效的东西,例如aaaaa,id将从URL中消失,但会一直显示在屏幕上(拥有ui组件的有状态性质).
但是......正如OP所提到的,只要发生任何验证器错误(例如进入a),id就会永久丢失.之后输入有效输入不会带回来.它几乎看起来像一个bug,但我尝试了Mojarra 2.1和Myfaces 2.1,两者都有相同的行为.
更新:
经过一番检查,问题似乎出现在这个'UIViewParameter'(Mojarra)的方法中:
public void encodeAll(FacesContext context) throws IOException {
if (context == null) {
throw new NullPointerException();
}
// if there is a value expression, update view parameter w/ latest value after render
// QUESTION is it okay that a null string value may be suppressing the view parameter value?
// ANSWER: I'm not sure.
setSubmittedValue(getStringValue(context));
}
Run Code Online (Sandbox Code Playgroud)
然后更具体地说这个方法:
public String getStringValue(FacesContext context) {
String result = null;
if (hasValueExpression()) {
result = getStringValueFromModel(context);
} else {
result = (null != rawValue) ? rawValue : (String) getValue();
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
因为hasValueExpression()它是真的,它将尝试从模型(支持bean)获取值.但由于这个bean是请求作用域,因此该请求没有任何值,因为验证刚刚失败,因此没有设置任何值.实际上,有状态值UIViewParameter被覆盖bean作为默认值返回的任何内容覆盖(通常为null,但它当然取决于你的bean).
一个解决方法是创建你的bean @ViewScoped,无论如何这通常都是一个更好的范围(我假设你使用参数从服务中获取用户,并且在每次回发时可能不必一次又一次地执行此操作).
另一种方法是创建自己的版本,UIViewParameter如果验证失败,则不会尝试从模型中获取值(基本上所有其他UIInput组件都会这样做).
| 归档时间: |
|
| 查看次数: |
4248 次 |
| 最近记录: |