1

我正在使用 HttpSession 作为实例变量,例如

@ManagedBean
@ViewScoped
public class CountryPages_Detail {

    private HttpSession session;

    public CountryPages_Detail() {
        session = ConnectionUtil.getCurrentSession();
    } //end of constructor

    public String preview() {
        session.setAttribute("countryDetailImageNames", imageNames);
        session.setAttribute("countryDetailImages", images);
        session.setAttribute("countrySummary", countrySummary);        
        return "countryPages_View?faces-redirect=true";

    } //end of preview()
} //end of  class CountryPages_Detail

ConnectionUtl 类:

 public static HttpSession getCurrentSession() {
     FacesContext facesContext = FacesContext.getCurrentInstance();
     ExternalContext externalContext = facesContext.getExternalContext();
     HttpServletRequest httpServletRequest = (HttpServletRequest) externalContext.getRequest();

     HttpSession currentSession = (HttpSession) externalContext.getSession(false);

     if (currentSession != null) {         
         return currentSession;
     } else {         
         return null;
     }
} //end of getCurrentSession()

我想问这是正确的方法吗?实际上我在我的 web.xml 中使用

<context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>server</param-value>
</context-param>

但是,当我将其更改为 时<param-value>client</param-value>,首先我得到了我的一个类不可序列化的异常,现在使其可序列化之后,我得到了异常

SEVERE: Error Rendering View[/index.xhtml]
java.io.NotSerializableException: org.apache.catalina.session.StandardSessionFacade
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1156)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509)
    ....

使用服务器时,它运行良好。为什么?我想问一下,我们什么时候在服务器中,param-value然后我们在 viewScope(@ViewScoped) 中的所有托管 bean 都驻留在服务器上,当我们将它更改为客户端时,那么我们所有的 @ViewScoped 托管 bean 都驻留在客户端上?此外,如果我的 bean 不在 @ViewScoped 中,那么 javax.faces.STATE_SAVING_METHOD 元素会产生什么不同吗?意味着 STATE_SAVING_METHOD 选项仅与 @ViewScoped 相关,或者它也影响 @RequestScope 或 @SessionScopr 或其他范围?谢谢

4

1 回答 1

2

绝对不应该获取外部上下文资源,例如HttpSession作为实例变量。只需在 threadlocal 范围内检索它。您可以使用它ExternalContext#sessionMap()来管理会话属性映射,而无需javax.servlet在您的 JSF 代码中导入(这通常表明您正在以错误或笨拙的方式做事,因此您在不使用 JSF 的情况下完全围绕 JSF 工作权力)。

public String preview() {
    Map<String, Object> sessionMap = FacesContext.getCurrentInstance().getExternalContext().getSessionMap();
    sessionMap.put("countryDetailImageNames", imageNames);
    sessionMap.put("countryDetailImages", images);
    sessionMap.put("countrySummary", countrySummary);        
    return "countryPages_View?faces-redirect=true";
}

然而,更好的是创建一个会话范围的托管 bean。你有一些奇怪的、相当程序化的和非面向对象的设计。

@ManagedBean
@SessionScoped
public class Country {

     private List<Something> detailImageNames;
     private List<Something> images;
     private Something summary;

     // ...
}

你在里面使用如下CountryPagesDetail

@ManagedProperty("#{country}")
private Country country;

public String preview() {
    country.setDetailImageNames(imageNames);
    country.setDetailImages(images);
    country.setSummary(summary);        
    return "countryPages_View?faces-redirect=true";
}

它是可用的#{country.detailImageNames}等等。

于 2012-05-22T14:01:43.383 回答