为何JSF验证会清除有效输入?附JSF 2.2 ManagedBean代码
JSF验证流程中有效内容被清除的原因及解决办法
兄弟,我来帮你捋捋这个问题——你遇到的JSF验证后有效内容被清掉的情况,大概率和你用的@RequestScoped作用域脱不了干系,再结合JSF本身的验证流程逻辑,就能找到根源了。
核心原因解析
1. 请求作用域的生命周期坑
你的RevisionBean标注了@RequestScoped,这意味着每一次HTTP请求(包括验证请求)都会生成一个全新的Bean实例。当用户提交表单时,JSF会先进入验证阶段:
- 如果有任何一个字段验证失败,JSF会直接跳过后续的更新模型、调用应用阶段,直接跳转到渲染响应阶段。
- 这时候新创建的Bean里,
revision是在构造方法里重新初始化的空对象,而用户之前输入的有效数据只存在于上一次请求的旧Bean里,新Bean根本拿不到,页面自然就显示空内容了。
2. JSF验证的模型更新规则
JSF有个严格的规则:只有当所有字段的验证都通过时,才会把用户输入的值更新到Bean的属性中。只要有一个字段验证失败,所有字段都不会更新到模型里。再加上请求作用域的Bean是每次请求新建,旧数据自然就丢失了。
解决办法
1. 换用@ViewScoped作用域(最推荐)
把@RequestScoped换成@ViewScoped,这个作用域会让Bean和当前页面视图绑定,只要用户停留在这个页面,Bean实例就会一直保留。哪怕验证失败,之前输入的有效数据也会存在Bean里,页面刷新后就能正常显示。修改后的Bean代码如下:
import javax.faces.bean.ManagedBean; import javax.faces.bean.ViewScoped; // 替换原来的RequestScoped import com.tss.model.Revision; import com.tss.services.RevisionService; @ManagedBean @ViewScoped public class RevisionBean implements Serializable { // 记得实现Serializable接口 private Revision revision; private RevisionService revisionService; public RevisionBean() { revision = new Revision(); revisionService = new RevisionService(); } public Revision getRevision() { return revision; } public void setRevision(Revision revision) { this.revision = revision; } // 其他未展示的方法保持不变 }
小提示:
@ViewScoped要求Bean实现Serializable,不然可能会出现序列化异常,记得加上哦。
2. 闪存临时存储(不推荐,太麻烦)
如果实在没法换作用域,可以在验证失败时,把用户输入的有效数据存到FacesContext的闪存(flash scope)里,然后在页面上优先从闪存取值。不过这种方式需要手动处理每个字段,代码量会增加很多,不如换作用域省心。
3. 检查验证规则是否合理
顺便检查下页面上的验证规则,比如有没有误加不必要的必填项,或者自定义验证器的逻辑有没有写错——要是明明输入有效却被判定为失败,也会触发这个问题。
内容的提问来源于stack exchange,提问作者rotaran
相关产品推荐
相关产品推荐

