我是 JSF 新手,我正在处理 JSF 应用程序的会话超时。我正在尝试使代码适用于 ajax 调用,但到目前为止无法实现。我尝试了两种方法:
方法 1:SessionListener(用于清理工作)和 SessionFilter(用于过滤每个请求并检查会话是否超时)我的过滤器代码片段:
if ((request instanceof HttpServletRequest)
&& (response instanceof HttpServletResponse)) {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
// is session expire control required for this request? (not required for home page or timeout page or JSF resources)
if (isSessionControlRequired(httpServletRequest)) {
// is session invalid?
if (isSessionInvalid(httpServletRequest)) {
String timeoutUrl = httpServletRequest.getContextPath() + "/timeout.html";
logger.info("session is invalid! redirecting to timeoutpage : " + timeoutUrl);
//httpServletResponse.sendRedirect(timeoutUrl);
//final FacesContext facesContext = FacesContext.getCurrentInstance();
//final ExternalContext externalContext = facesContext.getExternalContext();
//externalContext.dispatch("/start.jsp");
RequestDispatcher rd = httpServletRequest.getRequestDispatcher("/timeout.html");
rd.forward(httpServletRequest, httpServletResponse);
return;
}
}
}
chain.doFilter(request, response);
方法二:CustomeExceptionHandler 处理 ViewExpiredException handle() 的代码片段:
for (final Iterator<ExceptionQueuedEvent> it = getUnhandledExceptionQueuedEvents().iterator(); it.hasNext();) {
Throwable t = it.next().getContext().getException();
while ((t instanceof FacesException || t instanceof ELException) && null != t.getCause()) {
t = t.getCause();
}
if (t instanceof ViewExpiredException) {
final FacesContext facesContext = FacesContext.getCurrentInstance();
final ExternalContext externalContext = facesContext.getExternalContext();
final Map<String, Object> requestMap = externalContext.getRequestMap();
NavigationHandler nh = facesContext.getApplication().getNavigationHandler();
try {
final String viewId = ((ViewExpiredException) t).getViewId();
String message = "View has expired. " + viewId;
logger.error(message);
requestMap.put("errorMsg", message);
try {
requestMap.put("currentViewId", viewId);
nh.handleNavigation(facesContext, null, "/timeout.html");
facesContext.renderResponse();
// Force JSF to render the error page in its entirety to the ajax response.
//facesContext.setViewRoot(facesContext.getApplication().getViewHandler().createView(facesContext, "/timeout.html"));
//facesContext.getPartialViewContext().setRenderAll(true);
//facesContext.renderResponse();
//RequestContext rc = RequestContext.getCurrentInstance();
//rc.execute("addTitleDialog.show()");
//externalContext.dispatch("/start.jsp");
}
catch (final Exception e) {
logger.error("Cannot dispatch to /start.jsp");
}
facesContext.responseComplete();
}
finally {
it.remove();
}
}
else {
logger.error(t.getMessage(), t);
}
}
getWrapped().handle();
}
这两种方法都适用于非 ajax POST 调用,但不适用于 ajax 调用。当我在调试模式下运行我的应用程序时,我还可以单步执行 ajax 调用的所有语句,这让我知道控件确实来到了我的代码中,执行了它,但由于某种原因,UI 上没有任何反应。我一直在尝试将用户重定向到超时页面,但理想的做法是显示一个 JSF 对话框并在点击“确定”后将用户带到主屏幕(我的应用程序没有登录屏幕。)我也有一个基本问题,视图到期与会话超时完全相同吗?
任何帮助将不胜感激,谢谢,斯瓦蒂。