共计 4048 个字符,预计需要花费 11 分钟才能阅读完成。
某天深夜, 尼古拉斯. 李四 突发奇想: 给本人白天写的 10 个接口都打印下申请日志, 日志内容也很简略, 就打印下接口地址和申请参数就行了
然而这个打印申请日志的代码又不想在 10 个接口里都写上一遍, 咋办呢?
尼古拉斯. 李四开始左思右想, 左思右想 springmvc 的拦截器不就能够嘛
1. 自定义拦截器
实现 HandlerInteceptor 接口
HandlerInterceptor 接口中有三个办法
preHandle : 在进入 Controller 之前执行。返回值为 Boolean 类型,如果返回 false,示意拦挡申请,不再向下执行,如果返回 true,示意放行,程序持续向下执行(如果前面没有其余 Interceptor,就会执行 controller 办法)。所以此办法可对申请进行判断,决定程序是否继续执行,或者进行一些初始化操作及对申请进行预处理
postHandle: 在 Controller 办法调用完后, 在 DispatcherServlet 进行视图返回渲染之前被调用, 能够在这个办法中对 Controller 解决之后的 ModelAndView 对象进行操作,比如说设置 cookie,返回给前端
afterCompletion: 在整个申请完结之后执行,也就是在 DispatcherServlet 渲染了对应的视图之后执行, 所以该办法适宜进行一些资源清理
@Component
@Slf4j
public 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
@Configuration
public class TestMvcConfigure extends WebMvcConfigurerAdapter {
@Resource
private LogRequestUriInterceptor logRequestUriInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(logRequestUriInterceptor);
}
}
二. implements WebMvcConfigurer
@Configuration
public class WebMvcConfigure implements WebMvcConfigurer {
@Resource
private LogRequestUriInterceptor logRequestUriInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(logRequestUriInterceptor);
}
3. 启动我的项目, 测试申请
那如果须要增加多个拦截器呢
当然是再定义一个拦截器, 增加进去
自定义第二个拦截器
@Component
@Slf4j
public 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;
}
}
增加第二个拦截器
@Configuration
public 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
@Slf4j
public 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
@Slf4j
public 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;}
}
增加拦截器的逻辑进行调整
@Configuration
public 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);
}
}
}
启动我的项目, 测试申请
未完待续 …
正文完