在dwz界面操作会话超时时,有两种处理方法。一种是跳到登录页面,另一种是弹出登录对话框。
如果使用了shiro框架,由于会记录最后访问记录,重新登录后会跳转到最后访问页面。
对于第一种处理方法,在登录界面登录后会重定向到最后访问页面,这样就会脱离了dwz的navtab控制。
所以只能采取第二种方法,即弹出登录对话框。 重新登录后同样面临重定向问题。因为这时对话框要求返回dwz特有的响应数据。没办法,只好自己hack一下了。
ok,随便扫一眼shiro的源码,找到了一个切入点。不难发现,shiro处理登录的是FormAuthenticationFilter这个filter,就从这个地方动手术。要看懂下面手术内容,需要明白dwz界面内发出的请求都是一个ajax请求。
public class DWZLoginFilter extends FormAuthenticationFilter { @Override protected void issueSuccessRedirect(ServletRequest request, ServletResponse response) throws Exception { if(isAjaxRequest(request)){ PrintWriter writer = getWriterFromResponse(response); DWZJsonReply reply = new DWZJsonReply(); reply.setMessage("Login successful!"); reply.setForwardUrl(getForwardUrl(request)); writer.print(JsonService.getJsonMapper().toJson(reply)); } else WebUtils.redirectToSavedRequest(request, response, getSuccessUrl()); } public String getForwardUrl(ServletRequest request){ SavedRequest savedRequest = WebUtils.getAndClearSavedRequest(request); if(savedRequest != null && savedRequest.getMethod().equalsIgnoreCase(AccessControlFilter.GET_METHOD)){ return savedRequest.getRequestUrl(); } return getSuccessUrl(); } @Override protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) { setFailureAttribute(request, e); if(isAjaxRequest(request)){ PrintWriter writer = getWriterFromResponse(response); DWZJsonReply reply = new DWZJsonReply(); reply.setStatusCode(DWZJsonReply.ERROR); reply.setMessage("Login fail.Invalid username or password."); writer.print(JsonService.getJsonMapper().toJson(reply)); return false; } // login failed, let request continue back to the login page: return true; } public PrintWriter getWriterFromResponse(ServletResponse res){ HttpServletResponse response = (HttpServletResponse)res; response.setHeader("Content-type", "text/html;charset=UTF-8"); response.setCharacterEncoding("UTF-8"); try { return response.getWriter(); } catch (IOException e) { e.printStackTrace(); throw Exceptions.unchecked(e); } } public boolean isAjaxRequest(ServletRequest request) { return ((HttpServletRequest) request).getHeader("x-requested-with") != null; } }
大功告成。