在jsf中没有生成会话

时间:2010-11-04 10:27:53

标签: jsf jsf-2

在JSP中,有一个属性 session 用于请求中的禁用自动生成会话。

<%@page contentType="text/html" pageEncoding="UTF-8" session="false" %>

有没有办法在JSF2中做同样的事情?

由于

为什么呢?因为我们将公共注册表单页面作为应用程序中的默认页面。这是一个非常简单的表单,每次人(或机器人等)请求主页时都会创建会话。 ManagedBean是RequestScope,但JSF在第一个navegation请求中创建一个会话。

2 个答案:

答案 0 :(得分:7)

只是不要使用视图/会话作用域bean(因此只使用请求或应用程序作用域bean)并通过在以下上下文中设置以下上下文参数,将状态保存设置为client而不是(默认)server web.xml

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

然后JSF将不会创建会话,并且会在必要时将视图状态存储在表单中名为javax.faces.ViewState的隐藏输入字段中。

创建和管理会话的成本可以忽略不计。此外,在使用客户端视图状态保存时,您仍需要权衡(反)序列化视图状态和网络带宽的成本。


根据您的评论

更新

  

@BalusC是的,这可能是一个全球解决方案。但我只需要在这个公共页面中使用此方法。在其他页面中,我想要服务器端状态保存方法。

好吧,对啊。抱歉,我没有在JSF / Facelets中看到任何方法来禁用会话或更改基于每个请求的视图状态保存。我考虑使用纯HTML <form>而不是JSF <h:form>,让它提交到另一个JSF页面,并在与JSF页面关联的bean中使用@ManagedProperty。 E.g。

<form action="register.jsf" method="post">
    <input type="text" name="username" />
    <input type="password" name="password" />
    <input type="submit" />
</form>

@ManagedBean
@RequestScoped
public class Register {

    @ManagedProperty(value="#{param.username}")
    private String username;

    @ManagedProperty(value="#{param.password}")
    private String password;

    @PostConstruct
    public void init() {
        // Do your thing here.
        System.out.println("Submitted username/password: " + username + "/" + password);
    }

    // ...
}

答案 1 :(得分:2)

实际上,自从Mojarra 2.1.19 / 2.2.0起,BalusC的回答是不正确的。您可以在他的博客here中阅读相关内容。 现在完全足够了:

<f:view transient="true">
   Your regular content
</f:view>

如上所述:

  

尚未创建视图状态,因此在尚未创建会话时也不会创建会话。 [...]请记住将关联的托管bean放在请求范围而不是视图/会话范围内,否则您只是简单地忽略了“无状态”一词的含义。

com.sun.faces.application.view.FaceletViewHandlingStrategy类中的下一个代码段:

        /*
         * Make sure we have a session here if we are using server state
         * saving. The WriteBehindStateWriter needs an active session when
         * it writes out state to a server session.
         * 
         * Note if you flag a view as transient then we won't acquire the
         * session as you are stating it does not need one.
         */
        if (isServerStateSaving() && !viewToRender.isTransient()) {
            getSession(ctx);
        }      

另请注意某些第三方组件库,例如ICEfaces或其他框架,例如Apache Shiro可以为自己的目的自己创建会话。