在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;
}
}
大功告成。