本文介绍了JSF2 Viewscope验证问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试根据下拉列表值动态显示页面所有相关组件均正确呈现.当I bean在视图范围内时,验证不会触发,而同样适用于会话范围.任何人都可以帮忙我可以解决问题吗?

此处遵循我的Main.xhtml代码.此页面包含dropdownlist.基于动态的dropdown值(包括页面).

<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<ui:composition template="#{templates.standard}">
<ui:define name="contentArea">
<c:choose>
<c:when test="#{testBean.value == '1'}">
<h:panelGroup>
<ui:include src="Page1.xhtml" />
</h:panelGroup>
</c:when>
<c:when test="#{testBean.value == '2'}">
<h:panelGroup>
<ui:include src="Page2.xhtml" />
</h:panelGroup>
</c:when>
</c:choose>
</ui:define>
</ui:composition>
</html>

The below Page1.xhtml will be included dynamically in Main.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:panelGroup>
<h:inputText value="#{testBean1.date}"
id="date"
required="true" requiredMessage="Enter Valid date">
<f:validator validatorId="test.TestDateValidator" />
</h:inputText>
</h:panelGroup>
<h:panelGroup>
<h:message for="date"/>
</h:panelGroup>
解决方案

视图作用域的bean存储在JSF视图中. JSF视图仅在已构建时可用.诸如JSTL <c:xxx>之类的标记处理程序在视图构建期间运行.因此,它们在JSF视图可用之前运行.因此,当您将视图作用域的bean的属性绑定到JSTL标记属性时,它将不会引用JSF视图中的视图作用域的bean实例,而是引用所有属性均设置为default的新创建的实例. >

因此,基本上,您最终会在每个请求的基础上得到一个视图作用域Bean的两个不同实例.在还原视图时使用一个(在每个表单提交上都重新创建的一个),在处理表单提交时使用的另一个(实际存储在视图范围中的一个).

此鸡肉问题已报告为 JSF问题1492 ,并已针对以下问题进行了修复即将发布的JSF 2.2.

在那之前,最好的选择是创建一个单独的请求范围的bean,并让include条件取决于@ManagedProperty注入的请求参数,或者关闭部分状态保存(但是可能有内存/性能)含义).请注意,<ui:include>也在视图构建期间运行,因此将其包装在具有rendered属性的JSF组件中无济于事,因为它是在视图渲染期间进行评估的.

另请参见:

Trying to display the pages dynamically based on the dropdown list value.All the associated components are rendering properly.When I bean is in view scope the validations are not triggering whereas the samething is working fine with session scope.Could anyone please help me to resolve the issue?

Here follows my code of Main.xhtml This page contains the dropdownlist.Based on the dropdown value dynamically including the pages.

<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<ui:composition template="#{templates.standard}">
<ui:define name="contentArea">
<c:choose>
<c:when test="#{testBean.value == '1'}">
<h:panelGroup>
<ui:include src="Page1.xhtml" />
</h:panelGroup>
</c:when>
<c:when test="#{testBean.value == '2'}">
<h:panelGroup>
<ui:include src="Page2.xhtml" />
</h:panelGroup>
</c:when>
</c:choose>
</ui:define>
</ui:composition>
</html>

The below Page1.xhtml will be included dynamically in Main.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:panelGroup>
<h:inputText value="#{testBean1.date}"
id="date"
required="true" requiredMessage="Enter Valid date">
<f:validator validatorId="test.TestDateValidator" />
</h:inputText>
</h:panelGroup>
<h:panelGroup>
<h:message for="date"/>
</h:panelGroup>
解决方案

View scoped beans are stored in the JSF view. The JSF view is only available when it has been built. Taghandlers like JSTL <c:xxx> run during view build time. They thus run before the JSF view is available. So, when you bind a property of a view scoped bean to a JSTL tag attribute, then it would not refer the view scoped bean instance in the JSF view, but instead refer a freshly created one, with all properties set to default.

So, basically, you end up with two different instances of a view scoped bean on a per-request basis. One which is used during restoring the view (the one which is freshly recreated on every form submit) and another one which is used during processing the form submit (the one which was actually stored in the view scope).

This chicken-egg issue is already reported as JSF issue 1492 and fixed for the upcoming JSF 2.2.

Until then, your best bet is to create a separate request scoped bean and let the include condition depend on a request parameter which is injected by @ManagedProperty, or to turn off partial state saving (which may however have memory/performance implications). Note that the <ui:include> also runs during view build time, so wrapping it in a JSF component with the rendered attribute won't help anything as it is evaluated during view render time.

See also:

这篇关于JSF2 Viewscope验证问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-12 23:13