2

我有 JSF 页面,其中包含指向其他 JSF 页面的链接。当我单击链接并且会话已经过期时,控制转到登录页面。我将使用用户名密码登录,然后再次来到我点击链接的同一页面。现在我将单击链接,将显示一个空白页面,如果我按 F5 刷新页面,则会加载预期的页面。

而且我还检查了我的 Jboss 服务器上的控制台,没有出现 View Expired 异常。

所以我有点困惑我用哪种方式来处理这个以避免显示空白页。

请帮忙。

4

2 回答 2

2

如果您通过 ajax 执行链接导航,并且登录后返回的页面是从浏览器缓存提供的(因此包含具有过期视图状态标识符的表单),则可能会发生这种情况。您需要告诉浏览器不要缓存受限页面。您可以使用以下过滤器实现此目的:

@WebFilter(servletNames={"Faces Servlet"})
public class NoCacheFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;

        if (!req.getRequestURI().startsWith(req.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER)) { // Skip JSF resources (CSS/JS/Images/etc)
            res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
            res.setHeader("Pragma", "no-cache"); // HTTP 1.0.
            res.setDateHeader("Expires", 0); // Proxies.
        }

        chain.doFilter(request, response);
    }

    // ...
}

请注意,此问题因此也表明您正在使用(ajax)命令链接进行页面到页面导航。这是一个不好的做法。这些链接不是 SEO 友好的,也不是可收藏的。命令链接应仅用于表单提交。使用普通链接进行页面到页面导航。另请参阅何时应该使用 h:outputLink 而不是 h:commandLink?

于 2012-11-21T11:41:03.623 回答
0

@BaluSC:感谢您的回复。

尽可能使用 h:outputLink。
而且我还通过 web.xml 中的标记处理了 ViewExpiredException。

<error-page>
    <exception-type>java.lang.Exception</exception-type>
    <location>/ErrorHandler</location>
  </error-page>

<servlet>
    <servlet-name>ErrorHandler</servlet-name>
    <servlet-class>com.common.beans.ErrorHandler</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ErrorHandler</servlet-name>
    <url-pattern>/ErrorHandler</url-pattern>
  </servlet-mapping>

使用处理此异常并重定向到同一页面并正确加载页面的 servlet。Servlet 的 doGet 方法检查 ViewExpiredException。

public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException
 {

      if (request.getAttribute("javax.servlet.error.exception") != null
         && request.getAttribute("javax.servlet.error.exception")
            .toString().contains("ViewExpiredException"))
      {

            String[] attributes =
               request.getAttribute("javax.servlet.error.request_uri")
                  .toString().split("/");
            StringBuilder redirectViewId = new StringBuilder("");
            for (int i = 2; i < attributes.length; i++)
            {
               redirectViewId.append("/").append(attributes[i]);
            }
            response.sendRedirect(FacesUtils.getFullRequestUrl(request)
               + redirectViewId);
         }
}
于 2012-11-22T09:03:24.713 回答