当不使用URL参数时,在POST上重新创建的视图作用域bean



我有一个视图范围 jsf管理bean,它支持xhtml视图,我使用f:viewParam从URL读取一个参数。

视图向用户呈现表单。然而,当用户通过按p:commandButton提交表单时,似乎重新创建了视图作用域bean(我添加了一个@PostConstruct注释来验证这一点),因此不记得从f:viewParam读取的实例变量(invId在下面的代码中)。

我最初使用GET导航到包含URL参数的视图,但是当用户按下p:commandButton时发送的POST消息不包含URL参数。所以我认为,当JSF运行时没有在POST上看到URL参数时,它认为这是一个不同的视图,并且正在重新创建JSF管理的bean。当我将视图范围更改为会话范围时,代码可以工作。

代码如下:

<<h2>视图/h2>
<f:metadata>
    <f:viewParam name="invId" value="#{registerBean.invId}"/>
</f:metadata>
<h:form id="registrationForm">
     ....
    <p:commandButton value="register" action="#{registerBean.register}"
                     icon="ui-icon ui-icon-newwin" ajax="false"/>
</h:form>

支持bean

@ManagedBean                                      
@ViewScoped
public class RegisterBean implements Serializable {
    @ManagedProperty(value="#{invId}")
    private String invId;
    ...
<标题> 更新

事实证明,这与URL参数无关。下面的BalusC建议我删除了c:当标签我的视图正在使用(依靠渲染属性代替相同的效果),现在视图作用域的bean不再被重新创建,invId字段被正确保留。

这个问题在目前发布的代码中是不可见的,但是对于JSF 2.0/2.1来说,一个已知的问题是,当一个视图作用域bean的属性被绑定到标记处理程序(如JSTL <c:if>或Facelets <ui:include>)的属性或JSF组件(如idbinding)的视图构建时间属性时,视图作用域bean将被重新创建,而部分状态保存是启用的(默认情况下)。

后台解释是在构建和恢复视图期间执行这些属性中的任何EL表达式。由于视图作用域bean存储在视图中,因此只有在恢复视图后才能使用,这样的EL表达式求值将导致创建一个全新的单独的视图作用域bean。这基本上是一个先有鸡还是先有蛋的问题。这个问题将在即将发布的JSF 2.2中修复。

基本上有3种解决方案:

  1. 相应地更改视图,以便这些EL表达式仅在视图呈现时计算。例如,将<c:if>/<c:choose>替换为rendered
  2. 或者将这些属性绑定到一个请求作用域bean(设计注意:你可以直接注入一个视图作用域bean作为一个请求作用域bean的托管属性)。
  3. 关闭部分状态保存,如果需要的话,只针对特定的视图。

参见:

  • JSTL在JSF2 Facelets…有道理吗?
  • 标签处理程序中@ViewScoped失败

相关内容

  • 没有找到相关文章

最新更新