我有 JSF 页面,其中包含指向其他 JSF 页面的链接。当我单击链接并且会话已经过期时,控制转到登录页面。我将使用用户名密码登录,然后再次来到我点击链接的同一页面。现在我将单击链接,将显示一个空白页面,如果我按 F5 刷新页面,则会加载预期的页面。
而且我还检查了我的 Jboss 服务器上的控制台,没有出现 View Expired 异常。
所以我有点困惑我用哪种方式来处理这个以避免显示空白页。
请帮忙。
我有 JSF 页面,其中包含指向其他 JSF 页面的链接。当我单击链接并且会话已经过期时,控制转到登录页面。我将使用用户名密码登录,然后再次来到我点击链接的同一页面。现在我将单击链接,将显示一个空白页面,如果我按 F5 刷新页面,则会加载预期的页面。
而且我还检查了我的 Jboss 服务器上的控制台,没有出现 View Expired 异常。
所以我有点困惑我用哪种方式来处理这个以避免显示空白页。
请帮忙。
如果您通过 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?
@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);
}
}