2

这个问题与这个问题非常相似:Using JSF 2.0 / Facelets, is there a way to attach a global listener to all AJAX calls? 但是解决方案对我不起作用。我错过了一些东西。

问题是:当会话过期时,我单击一些 ajax 链接/按钮并发送重定向(来自Filter)浏览器不更新页面 接收最后一个非 AJAX 请求的页面

我所拥有的是:

  1. WebSphere 上的 JSF 2.1(我也使用 Richfaces 4.2.0)
  2. 我使用 AJAX(登录后的第一个请求除外)
  3. @ManagedBean(name = "user") @SessionScoped UserBean与字段一起使用User user(这又是用于用户访问管理的 EJB 实体类)
  4. 我使用 OmniFaces 类来执行FullAjaxExceptionHandler(没有我的过滤器它工作正常,感谢 BalusC)
  5. 我使用javax.servlet.Filter映射到来@WebFilter("*.xhtml")管理对资源的访问和登录检查。doFilter()函数片段:

    ....
    if (user == null) { // if user is not logged in
         redirectToLogin(req, res);
    }
    

    并且在同一个 Filter 类中有redirectToLogin()函数(再次感谢 BalusC (= ):

    private static final String FACES_REDIRECT_XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
        + "<partial-response><redirect url=\"%s\"></redirect></partial-response>";
    
    protected void redirectToLogin(ServletRequest req, ServletResponse res) throws IOException {
        HttpServletRequest request = (HttpServletRequest) req;
    
        if ("partial/ajax".equals(request.getHeader("Faces-Request"))) {
            res.setContentType("text/xml");
            res.setCharacterEncoding("UTF-8");
            res.getWriter().printf(FACES_REDIRECT_XML, request.getContextPath() + "/login.xhtml");
        } else {
            String url = request.getContextPath() + "/login.xhtml";
            HttpServletResponse resHttp = (HttpServletResponse) res;
            resHttp.sendRedirect(url);
        }
    }
    

当会话过期时,我单击了一些 ajax 链接/按钮(发生 ViewExpiredException)。我可以在调试中看到字符串res.getWriter().printf(FACES_REDIRECT_XML, request.getContextPath() + "/login.xhtml");执行。我还可以看到 HTTP REDIRECT 请求和响应登录.xhtml那不是登录页面,这是上次发出非 AJAX 请求的旧页面!) Firebug 中的页面,但浏览器不更新视图.

我能否以某种方式检测到过滤器(FacesContext 外部)中发生 ViewExpiredException 并将控制权传递给 FullAjaxExceptionHandler?(顺便说一句,如果可能的话,我不再需要 ajaxExceptionHandler 来处理 ViewExpiredException,对吧?)浏览器页面没有更新的原因是什么?

正如我在帖子顶部提到的那样,我阅读并遵循了相关帖子的指导方针,但我错过了一些东西或误解了。会是什么呢?

谢谢。


更新:我收到的 HTML 代码是上次非 AJAX 请求返回的旧 HTML 页面!所以问题是 FacesServlet 不会将我的 login.xhtml 发送到客户端的浏览器。

Update2:我发现我从 FasesServlet 收到的页面是最后一个非 AJAX 请求的页面(在我的情况下,这是我成功登录后看到的第一个视图)。(顺便说一句,浏览器仍然没有更新页面,并且存在由这一行引起的 XML 解析错误<!DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >:)


更新3: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.PARTIAL_STATE_SAVING</param-name>
        <param-value>true</param-value>
    </context-param>

    <context-param>
        <param-name>facelets.DEVELOPMENT</param-name>
        <param-value>true</param-value>
    </context-param>
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>

    <session-config>
        <session-timeout>
            1
        </session-timeout>
    </session-config>
    <context-param>
        <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
        <param-value>true</param-value>
    </context-param>    

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>login.xhtml</welcome-file>
    </welcome-file-list>
    <context-param>
        <param-name>javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE</param-name>
        <param-value>true</param-value>
    </context-param>       


    <error-page>
        <error-code>500</error-code>
        <location>/errors/500.xhtml</location>
    </error-page>
    <error-page>
        <exception-type>javax.faces.application.ViewExpiredException</exception-type>
        <location>/loginViewExpired.xhtml</location>
    </error-page>

</web-app>
4

0 回答 0