某天深夜, 尼古拉斯.李四 突发奇想: 给本人白天写的10个接口都打印下申请日志, 日志内容也很简略, 就打印下接口地址和申请参数就行了
然而这个打印申请日志的代码又不想在10个接口里都写上一遍, 咋办呢?
尼古拉斯.李四开始左思右想,左思右想 springmvc的拦截器不就能够嘛
1. 自定义拦截器
实现HandlerInteceptor接口
HandlerInterceptor接口中有三个办法preHandle : 在进入Controller之前执行。返回值为Boolean类型,如果返回false,示意拦挡申请,不再向下执行,如果返回true,示意放行,程序持续向下执行(如果前面没有其余Interceptor,就会执行controller办法)。所以此办法可对申请进行判断,决定程序是否继续执行,或者进行一些初始化操作及对申请进行预处理postHandle: 在Controller办法调用完后, 在DispatcherServlet 进行视图返回渲染之前被调用, 能够在这个办法中对Controller 解决之后的ModelAndView 对象进行操作,比如说设置cookie,返回给前端afterCompletion: 在整个申请完结之后执行,也就是在DispatcherServlet 渲染了对应的视图之后执行, 所以该办法适宜进行一些资源清理@Component@Slf4jpublic class LogRequestUriInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String requestURI = request.getRequestURI(); Map<String, String[]> parameterMap = request.getParameterMap(); log.info("==收到申请, requestURI: {} , queryString: {} ==", requestURI, JsonUtil.toJsonDisableHtmlEscaping(parameterMap)); return true; }}
2. 增加拦截器 (有两种形式, 这里抉择第二种)
一. extends WebMvcConfigurerAdapter (spring5.0开始废除)
WebMvcConfigurerAdapter
@Configurationpublic class TestMvcConfigure extends WebMvcConfigurerAdapter { @Resource private LogRequestUriInterceptor logRequestUriInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(logRequestUriInterceptor); }}
二. implements WebMvcConfigurer
@Configurationpublic class WebMvcConfigure implements WebMvcConfigurer { @Resource private LogRequestUriInterceptor logRequestUriInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(logRequestUriInterceptor); }
3. 启动我的项目, 测试申请
那如果须要增加多个拦截器呢
当然是再定义一个拦截器,增加进去
自定义第二个拦截器
@Component@Slf4jpublic class RecordLogInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info("==自义定拦截器2, uri: {} ,queryString: {} ==", request.getRequestURI(), JsonUtil.toJsonDisableHtmlEscaping(request.getParameterMap())); return true; }}
增加第二个拦截器
@Configurationpublic class WebMvcConfigure implements WebMvcConfigurer { @Resource private LogRequestUriInterceptor logRequestUriInterceptor; @Resource private RecordLogInterceptor recordLogInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(logRequestUriInterceptor); registry.addInterceptor(recordLogInterceptor); }}
启动我的项目, 测试申请
从打印的日志能够看出, 此时拦截器失效的程序是和增加的程序统一的
又一个风雨交加的深夜, 尼古拉斯.李四 夜不能寐, 感觉下面增加多个拦截器的形式能够调整一下, 不便隔壁老王.王五再新增自定义拦截器时, 只须要定义拦截器 不在须要须要去手动增加了
革新开始
新建一个带排序办法的形象公共拦截器
public abstract class AbstractHandlerInterceptor implements HandlerInterceptor { /** * 有了这个办法, 就能够按程序主动增加拦截器 * @return */ abstract Integer sort();}
拦截器1 改实现为继承
@Component@Slf4jpublic class LogRequestUriInterceptor extends AbstractHandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String requestURI = request.getRequestURI(); Map<String, String[]> parameterMap = request.getParameterMap(); log.info("==自定义拦截器1, requestURI: {} , queryString: {} ==", requestURI, JsonUtil.toJsonDisableHtmlEscaping(parameterMap)); return true; } @Override Integer sort() { return 1; }}
拦截器2改实现为继承
@Component@Slf4jpublic class RecordLogInterceptor extends AbstractHandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info("==自义定拦截器2, uri: {} ,queryString: {} ==", request.getRequestURI(), JsonUtil.toJsonDisableHtmlEscaping(request.getParameterMap())); return true; } @Override Integer sort() { return 2; }}
增加拦截器的逻辑进行调整
@Configurationpublic class WebMvcConfigure implements WebMvcConfigurer { @Resource private ApplicationContext applicationContext; @Override public void addInterceptors(InterceptorRegistry registry) { Map<String, AbstractHandlerInterceptor> interceptorMap = applicationContext.getBeansOfType(AbstractHandlerInterceptor.class); Set<AbstractHandlerInterceptor> treeSet = new TreeSet<AbstractHandlerInterceptor>((o1, o2) -> o1.sort() - o1.sort()); treeSet.addAll(interceptorMap.values()); for (AbstractHandlerInterceptor interceptor : treeSet) { registry.addInterceptor(interceptor); } }}
启动我的项目, 测试申请
未完待续...