我有JSF页面,其中包含指向其他JSF页面的链接。当我单击链接并且会话已经过期时,控制权将转到登录页面。我将使用用户名密码登录并再次访问我点击链接的同一页面。现在我将点击链接,显示空白页面,如果我按F5页面刷新,则预期页面加载。
而且我已经检查了我的Jboss服务器上的控制台,View Expired异常没有出现。
所以我有点困惑,我处理这个以避免显示空白页面。
请帮忙。
答案 0 :(得分: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友好的,也不是可收藏的。命令链接仅应用于表单提交。使用普通链接进行页面到页面导航。另请参阅When should I use h:outputLink instead of h:commandLink?
答案 1 :(得分: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);
}
}