【问题标题】:No session generation in jsfjsf中没有会话生成
【发布时间】:2011-05-04 23:42:24
【问题描述】:

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

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

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

谢谢

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

【问题讨论】:

  • @BalusC 添加了有问题的原因。

标签: jsf jsf-2


【解决方案1】:

只是不要使用视图/会话范围的 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 &lt;form&gt; 而不是 JSF &lt;h:form&gt;,让它提交到另一个 JSF 页面并在与 JSF 页面关联的 bean 中使用 @ManagedProperty。例如

<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);
    }

    // ...
}

【讨论】:

    【解决方案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 类中的下一个代码 sn-p:

            /*
             * 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);
            }      
    

    还要注意一些 3rd-party 组件库,例如ICEfaces 或其他框架,例如Apache Shiro,可以出于某种目的自己创建会话。

    【讨论】:

      猜你喜欢
      • 2011-12-10
      • 2011-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-18
      • 2022-01-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多