在SpringMvc中一般都是用Filter拦截浏览器的请求,但是为了实现更精准化的拦截可以通过继承HandlerInterceptorAdapter适配器类来实现。
HandlerInterceptorAdapter是一个抽象类,类中定义了三个方法,通过重写父类的方法实现精准拦截
public abstract class HandlerInterceptorAdapter
implements HandlerInterceptor
{
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception
{
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception
{}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception
{}
}
preHandle:预处理回调方法,实现处理器的预处理(如登录检查),第三个参数为响应的处理器;
返回值:true表示继续流程(如调用下一个拦截器或处理器);
false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应;
postHandle:后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null。
afterCompletion:整个请求处理完毕回调方法,即在视图渲染完毕时回调,如性能监控中我们可以在此记录结束时间并输出消耗时间,还可以进行一些资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中preHandle返回true的拦截器的afterCompletion。
下面贴一段自己项目中用到的例子,通过重写preHandle方法进行登录检查
public class FormRepeatSubmitInterceptor extends HandlerInterceptorAdapter {
private String formKeyName = "PrivateFromSubmitKey";
public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
String oldKey = (String)session.getAttribute(formKeyName);
String newKey = generateToken(session);
if(oldKey == null || "".equals(oldKey)){
session.setAttribute(formKeyName, newKey);
}
String formKey = (String)request.getParameter(formKeyName);
if(formKey == null || "".equals(formKey)){
return true;
}
if(oldKey.equals(formKey)){
session.setAttribute(formKeyName, newKey);
return true;
}else{
String repeatSubmitErrorUrl = "/error_wordcensor.kq";
response.sendRedirect(request.getContextPath()+repeatSubmitErrorUrl);
return false;
}
}
protected String generateToken(HttpSession session) {
try {
byte id[] = session.getId().getBytes();
byte now[] = new Long(System.currentTimeMillis()).toString().getBytes();
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(id);
md.update(now);
BigInteger a = new BigInteger(md.digest());
return a.toString(16);
} catch (IllegalStateException e) {
return (null);
} catch (NoSuchAlgorithmException e) {
return (null);
}
}
}