一、简介
SpringMVC 的拦截器处理器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。
二、常见的应用场景
1、日志记录 :记录请求信息的日志。
2、权限检查,如登录检查。
3、性能检测:检测方法的执行时间。
三、具体使用
下面的例子通过拦截器实现登录检查功能。
1、配置
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/"/>
<mvc:exclude-mapping path="/index"/>
<mvc:exclude-mapping path="/login"/>
<mvc:exclude-mapping path="/getCaptcha"/>
<mvc:exclude-mapping path="/logger"/>
<mvc:exclude-mapping path="/logDownload"/>
<mvc:exclude-mapping path="/metrics"/>
<mvc:exclude-mapping path="/health"/>
<mvc:exclude-mapping path="/cms/**"/>
<mvc:exclude-mapping path="/static/**"/>
<mvc:exclude-mapping path="/taskInfo/index/mqRecord"/>
<mvc:exclude-mapping path="/process/queryMQRecordTypes"/>
<mvc:exclude-mapping path="/process/queryMQRecord"/>
<mvc:exclude-mapping path="/process/queryMQCharts"/>
<mvc:exclude-mapping path="/system/noticeContent/pushMessage"/>
<mvc:exclude-mapping path="/faceRecognition/resultNotification"/>
<mvc:exclude-mapping path="/faceRecognition/scoreResultNotification"/>
<bean class="com.billionsfinance.crs.common.web.SecurityInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
<mvc:interceptors>表示可以配置多个拦截器进行顺序拦截。
<mvc:interceptor>表示配置其中一个拦截器。
<mvc:mapping path="/**"/>需要拦截的请求的url,可以使用通配符,示例表示拦截所有请求。
<mvc:exclude-mapping path="/index"/>表示不进行拦截的请求url。
<bean class="com.billionsfinance.crs.common.web.SecurityInterceptor"/> 表示自定义的拦截器实现类,用于实现拦截的业务逻辑。
2、实现自定义拦截器
public class SecurityInterceptor extends HandlerInterceptorAdapter {
/**
* 在进入controller之前执行
*
* @param request 请求
* @param response 响应
* @param handler 前一个拦截
* @return true or false
* @throws Exception ex
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object user = request.getSession().getAttribute(CrsConstants.CURRENT_USER);
if (null == user) {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
// 未登录
if (WebUtils.isAjaxRequest(request)) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setHeader("sessionstatus", "timeout"); //在响应头设置session状态
} else {
PrintWriter out = response.getWriter();
StringBuilder builder = new StringBuilder();
builder.append("<script type=\"text/javascript\" charset=\"UTF-8\">");
builder.append("alert(\"登录超时,请重新登录!\");");
builder.append("window.top.location.href=\"");
builder.append(request.getContextPath());
builder.append("\"</script>");
out.print(builder.toString());
out.close();
}
return false;
}
return true;
}
}
上面的代码实现了一个自定义拦截器,首先需要继承 HandlerInterceptorAdapter 。然后根据需要覆写 preHandle , postHandle 和 afterCompletion 方法。
三个方法的作用如下:
preHandle :该方法将在请求处理之前进行调用。多个Interceptor时,SpringMVC会根据声明的前后顺序一个接一个的执行,而且所有的Interceptor方法都会在 Controller方法调用之前调用。SpringMVC的这种Interceptor链式结构也是可以中断的,中断方式是令 preHandler 的返回值为 false ,当prehandler的返回值为false时整个请求就结束了。
postHandle:在当前请求进行处理之后,也就是Controller 方法调用之后执行,但是它会在DispatcherServlet进行视图返回渲染之前被调用。所以,我们可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作。
afterCompletion :该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。这个方法的主要作用是用于进行资源清理工作的。
上面的例子覆写了preHandle 方法在controller 方法调用之前进行登录检查。