如何在JSF应用程序中检查有效的会话?

时间:2018-08-08 18:05:13

标签: ajax jsf primefaces

在我解释这种情况之前,我会先说一下我正在处理的应用程序是旧的,过时的,需要重写的,等等。但是我工作的公司不在乎,而只是在寻找快速绷带解决这个问题。而且,我只是他们提供给此应用程序的一个随机家伙,尽管几乎不了解所有这些内容,但他们还是以某种方式将我视为主题专家。

我有一个.xhtml页面,用户可以转到该页面以支付账单。我们使用SiteMinder控制对应用程序的访问,并为此设置了两个小时的不活动超时限制。但是,我们最近从第三方供应商处实现了一些新的付款功能,这些功能使用了模式窗口。如果用户在此.xhtml页面上坐了一个小时零五十九分钟,调用了模式窗口(通过单击按钮),并完成了模式中的各种操作,那么当他们完成后,第三方供应商会认为操作成功(因为他们不知道我们的超时),但是由于会话在我们端超时,我们没有收到他们的任何回复。这是一个问题,因为用户可以安排将来的付款,而且如果我们没有收到供应商的答复,则我们将没有什么存储在数据库中,最终我们将使用该数据来触发安排的付款。

当他们单击以调用第三方模式窗口时,如何确定用户的会话是否仍然有效?这是其中一个按钮的外观:

<p:commandButton id="makePaymentButton" 
    value="Make Payment" onclick="makePayment(/*args*/);"
</p:commandButton>

基本上,而不是立即调用模式窗口,我想首先检查并确保用户的会话仍然有效。由于单击此按钮时没有页面导航或服务器交互,因此该模式仅呈现用户会话是否已过期。

2 个答案:

答案 0 :(得分:3)

如果使用标准渲染工具包,请使用:

<h:commandButton id="makePaymentButton"
                 value="Make Payment" 
                 actionListener="your action listener which may return an exception if the session control fails">
    <f:ajax onevent="makePayment(/*args*/)" />
</h:commandButton>

如果您使用Primefaces,请使用“不完整”,“不成功”:

<p:commandButton id="makePaymentButton" 
                 value="Make Payment" 
                 actionListener="your action listener which may return an exception if the session control fails" 
                 onsuccess="makePayment(/*args*/)" />

然后,在actionListener中,您可以获取会话:

HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);

警告:会话引用可能为空,然后检查您的需要。

不要忘记放置<f:view transient="true"> ... </f:view>来禁止自动创建JSESSIONID。

答案 1 :(得分:2)

要知道会话是否仍然有效,您需要询问服务器。但是您必须要小心,以免您的“询问”请求本身不会自动创建新的会话。最确定的方法是完全放弃JSF并创建一个简单的Servlet。

public class CheckSessionServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/plain");

        HttpSession session = request.getSession(false);
        if (session == null) {
            // no session, let's respond 404
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
        } else {
            // session exists - return a succesful status
            response.setStatus(HttpServletResponse.SC_NO_CONTENT);
        }
    }

}

使用JS对这个servlet进行AJAX POST请求,然后对请求结果进行处理。

为了防止用户在填写第三方对话框时会话超时,您可能需要触摸会话以使其超时:

        } else {
            // session exists - bump timeout & return a succesful status
            session.setAttribute("someUnusedAttribute", 123);
            response.setStatus(HttpServletResponse.SC_NO_CONTENT);
        }

如果会话已过期,则可以刷新页面(使用JS),以允许用户重新开始。或向用户显示一条简单消息,说明会话已消失,他需要重新开始。

您可以执行所有这些操作而无需接触旧版JSF。