是否有可能使JSF恢复用户输入的值而不管数据是否有效?

时间:2016-02-17 13:43:30

标签: jsf jsf-2.2

我正在开发一个表格为

的JSF应用程序
<h:inputText value="#{model.firstname}" />
<h:inputText value="#{model.employeeNumber}" converter="javax.faces.Integer"/>
...

这是使用bean验证的模型:

@NotNull(message="Please enter a surname")
private String firstname;

@Min(value=1)
@Max(value=2000)
private Integer employeeNumber;
...
//setters and getters

除了明确编码的&#39; back&#39;之外,一切都很好用。页面中的按钮转到上一页/表单。

我希望用户输入的值在返回上一页时再次恢复,无论数据是否有效。例如,如果用户将abc输入employeeNumber字段,则此字符串无法存储到模型上的Integer

我知道JSF将用户输入的值存储到&#34;请求值&#34;对于每个UIComponent。正是这些我想要恢复而不是我的模型,因为上面的表格还没有验证它的数据。

我该怎么做?

(当用户点击提交时,将进行数据验证。)

2 个答案:

答案 0 :(得分:2)

我过去只处理过这个问题 - 不使用@NotNull@Min@Max等验证注释。使用这些注释时,无效数据无法应用于模型,因此无法将状态保存在服务器上。

相反,我必须在Submit按钮后面的方法中编写验证逻辑。缺点是JSF没有为你工作;你必须自己做。好处是你可以更准确地控制验证的确切时间和方式。

答案 1 :(得分:2)

  

我的同事刚才提到可能有办法用omnifaces来实现这个目标

截至目前,有。 OmniFaces已经有很多东西可用,除了只有一个小的缺失关键部分。我只是committed一个Hacks#getStateHelper()到2.3 SNAPSHOT,它应该将受保护的UIComponent#getStateHelper()方法公开。然后,自1.0以及EditableValueHolderStateHelper以来已经在OmniFaces中使用<o:form> and <o:ignoreValidationFailed>的帮助,无论转换/验证错误如何(如“后退”按钮应该这样),都可以调用动作。

因此,如果您确定至少使用OmniFaces 2.3(目前仅作为SNAPSHOT使用),那么您可以使用以下会话范围的帮助bean来实现此要求,并使用多个OmniFaces实用程序类Faces,{{1 }和Hacks

EditableValueHolderStateHelper

需要在表单组件的@Named @SessionScoped public class Forms implements Serializable { private transient Map<String, StateHelper> states = new ConcurrentHashMap<>(); public void saveState(ComponentSystemEvent event) { UIComponent form = event.getComponent(); FacesContext context = Faces.getContext(); StateHelper state = Hacks.getStateHelper(form); EditableValueHolderStateHelper.save(context, state, form.getFacetsAndChildren()); states.put(Faces.getViewId(), state); } public void restoreState(ComponentSystemEvent event) { StateHelper state = states.get(Faces.getViewId()); if (state != null) { UIComponent form = event.getComponent(); FacesContext context = Faces.getContext(); EditableValueHolderStateHelper.restore(context, state, form.getFacetsAndChildren()); } } public void removeState() { states.remove(Faces.getViewId()); } } 事件期间调用saveState。需要在表单组件的postValidate事件期间调用restoreState()。在成功操作期间需要调用postAddToView。以下是一个示例表单:

removeState()

这种方法的主要优点是不需要修改现有的验证规则和支持bean,因此保留了JSF和BV的所有优点。

每当您在关联表单的组件树结构中进行更改时,请确保清除服务器会话状态和/或增加<o:form> <f:event type="postAddToView" listener="#{forms.restoreState}" /> <f:event type="postValidate" listener="#{forms.saveState}" /> <h:inputText value="#{bean.string}" required="true" /> <h:inputText value="#{bean.integer}" required="true" /> <h:commandButton value="save" actionListener="#{forms.removeState()}" action="#{bean.save}" /> <h:commandButton value="back" action="#{bean.back}"> <o:ignoreValidationFailed /> </h:commandButton> <h:messages /> </o:form> serialVersionUID,否则您必须进行预先检查和/或妥善处理异常。为表单和输入组件提供固定ID也是strongly recommended