@SessionScoped bean作为MyViews中的@RequestScoped的@ViewScoped的@ManagedProperty注入,在Mojarra中可以正常工作 [英] @SessionScoped bean injected as @ManagedProperty of a @ViewScoped acts like @RequestScoped in MyFaces, works fine in Mojarra

查看:89
本文介绍了@SessionScoped bean作为MyViews中的@RequestScoped的@ViewScoped的@ManagedProperty注入,在Mojarra中可以正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的简单示例:

Index.xhtml:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        <title>Title</title>
    </h:head>
    <h:body>
        <h:form>
            <h:inputText value="#{index.variable}"></h:inputText>
            <h:commandButton action="#{index.submit()}" type="submit"></h:commandButton>
        </h:form>
    </h:body>
</html>

它的ManagedBean:

Its ManagedBean:

import java.io.IOException;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;

@ManagedBean
@ViewScoped
public class Index implements Serializable {

    @ManagedProperty("#{sessionBean}")
    private SessionBean sessionBean; /*getter&setter*/
    private String variable; /*getter&setter*/

    public void submit() {
        sessionBean.setAsd(variable);
        ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
        try {
            context.redirect("next");
        } catch (IOException ex) {
        }
    }
}

/next/index.xhtml:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        <title>Check variable</title>
    </h:head>
    <h:body>
        #{sessionBean.asd}
    </h:body>
</html>

SessionBean.java:

import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean
@SessionScoped
public class SessionBean implements Serializable {

    private String asd;

    public String getAsd() {
        return asd;
    }

    public void setAsd(String asd) {
        this.asd = asd;
    }
}


如果我使用mojarra实现,一切都会按预期进行:提交表单后,用户将重定向到root/,并看到以index.xhtml形式打印的值.


If I use mojarra implementation everything works as expected: after form submitting, user gets redirected to root/ and see the value that was printed in the form of index.xhtml.

但是,如果我使用myfaces,则asd会在提交现有表单后立即变为null. SessionScoped bean的行为类似于RequestScoped

But if I use myfaces, asd becomes null right after existing form gets submitted. SessionScoped bean acts like RequestScoped

为什么?

这是我的web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
    <listener>
        <listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
        <!--listener-class>com.sun.faces.config.ConfigureListener</listener-class-->
    </listener>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <welcome-file-list>
        <welcome-file>index.xhtml</welcome-file>
    </welcome-file-list>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
</web-app>

服务器:Apache Tomcat 7.0.34

Server: Apache Tomcat 7.0.34

更新:如果我们将Index.java beanViewScoped批注更改为RequestScopedSessionScoped,则此方法有效.但是为什么呢?

UPDATE: it works if we change the ViewScoped annotation of Index.java bean to RequestScoped or SessionScoped. But why?

推荐答案

我目前有一个在Mojarra的帮助下编写的JSF 2.1项目.只是为了进行实验,我将实现更改为MyFaces并运行该应用程序,只是看到与您类似的问题(所有我注入的@ManagedProperty变量在POST提交后最终都为null).我切换回Mojarra,应用运行正常.因此,在MyFaces实施中基本上有所不同.

I currently have a JSF 2.1 project written with the help of Mojarra. Just for experimenting, I changed the implementation to MyFaces and ran the application only to see issues similar to yours (all my injected @ManagedProperty variables end up null after a POST submit). I switched back to Mojarra and the app runs fine. So, basically something is different in the MyFaces implementation.

仔细搜索使我想到了这个未解决的问题- MYFACES-3656 .以下是问题记者的摘录,内容涉及如何解决该问题:

A bit of googling led me to this unresolved issue - MYFACES-3656. Here's an excerpt from the issue reporter on how to fix the issue:

如果将 org.apache.myfaces.SERIALIZE_STATE_IN_SESSION 设置为错误 并重新部署该应用程序,然后一切都会按预期工作.

If you set the org.apache.myfaces.SERIALIZE_STATE_IN_SESSION to false and redeploy the application then everything works as expected.

这有什么帮助?答案在

How does this help? The answer is in the comments section:

我认为所描述的行为是预期的(不同的是 所描述的行为是希望的或有意采取的方式.

I think the behavior described is expected (different to say that the behavior described is desired or intentionally done in that way).

这是在MyFaces中发生的事情,序列化被设置为true 默认值(JSF 1.0规范中的一些旧行表示,即使RI不 以这种方式实施).在JSF 2.2规范中,SERIALIZE_STATE_IN_SESSION param将被标准化,默认情况下设置为false.

What's happening here is in MyFaces serialization is set to true by default (some old lines from JSF 1.0 spec says so, even if RI does not implement it in this way). In JSF 2.2 spec, SERIALIZE_STATE_IN_SESSION param will be standardized and set to false by default.

序列化导致视图范围内的所有bean实际上都是 重新创建".如果参数设置为false,则将Bean存储到 会话和进一步的请求被使用,看起来一切都很好 可以,但是事实并非如此,因为在群集配置中, 同一应用程序将失败.

Serialization causes that all beans under view scope are in fact "recreated". If the param is set to false, the beans are stored into session and on further requests are used, looking like everything is ok, but that fact is not true because in a cluster configuration the same application will fail.

仅在第一次创建视图范围Bean时,引用 从托管属性生效,但是如果bean是 序列化/反序列化后,引用不会恢复,因为 在序列化步骤上,甚至是应用程序和会话范围 豆也被序列化.

Only the first time the view scope bean is created, the references from managed-property takes effect, but if the bean is serialized/deserialized, the references are not restored back, because on the serialization step, even the application and session scope beans are serialized too.

.....

如何解决?我尚未找到解决此问题的合适方法.一 可以考虑只还原视图范围bean并重新应用 在faces-config.xml中找到@ManagedProperty批注或条目,但是 问题是视图范围bean仍在存储以下信息: 从一开始就不应该在那里(只能将字段标记为瞬态 会成功的).可以定义一个特殊的模式 hack或某些变体已完成,但这只会出现在我的脸上,而且 默认情况下无法启用.

How to solve it? I haven't found a decent solution to this issue. One could think on just restore the view scope bean and reapply @ManagedProperty annotations or entries found in faces-config.xml, but the problem is the view scope bean still is storing information that shouldn't be there from start (only marking the fields as transient will do the trick). It is possible define an special mode were this hack or some variant is done, but it will be only in myfaces and it cannot be enabled by default.

在此现在,由于您没有明确设置STATE_SAVING_METHOD,因此它默认为服务器.因此,SERIALIZE_STATE_IN_SESSION生效并默认为true.

Now, since in your case you are not explicitly setting a STATE_SAVING_METHOD, it defaults to server. Consequently, SERIALIZE_STATE_IN_SESSION comes into effect and defaults to true.

我在Tomcat上使用MyFaces尝试了您的代码,并将SERIALIZE_STATE_IN_SESSION设置为false,并且可以正常工作.但是,如果将STATE_SAVING_METHOD设置为 client ,则将无法进行任何操作,并且会出现未找到视图状态的错误.

I tried your code with MyFaces on Tomcat and set SERIALIZE_STATE_IN_SESSION to false and it works. However, in the event, you set the STATE_SAVING_METHOD to client, nothing will work and you'll get a view state not found error.

这篇关于@SessionScoped bean作为MyViews中的@RequestScoped的@ViewScoped的@ManagedProperty注入,在Mojarra中可以正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆