理论我的项目开发过程中,必定有这样的需要:
- 记录每个rest申请消耗的工夫,入参,出参
- 某些申请须要判断是否有权限,某些申请是不须要权限也能够运行的
这个需要太广泛了。明天咱们就一起来学习这个需要的两种实现形式:
- 拦截器
- 过滤器
拦截器
话不多说,咱们上代码,新建日志拦截器:
@Componentpublic class LogInterceptor implements HandlerInterceptor { //在申请rest接口之前调用 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("申请url:"+request.getRequestURL()); Map<String, String[]> parameterMap = request.getParameterMap(); Enumeration<String> parameterNames = request.getParameterNames(); System.out.println("申请参数:"); while (parameterNames.hasMoreElements()) { String name = (String) parameterNames.nextElement(); String value = request.getParameter(name); System.out.println(name+"==>"+value); } //假如参数a传递的如果是1的话,是不非法的申请,不持续往下执行 if("1".equals(request.getParameter("a"))){ return false; } return true;//如果返回false则不会持续往下执行,不会真正的进入到controller } //申请解决之后进行调用,然而在视图被渲染之前(Controller办法调用之后) @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle is called..."); } //在整个申请完结之后被调用 @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion is called..."); }}
在WebMvcConfigurer
中注册该拦截器,并通知spring
哪些门路须要拦挡,哪些门路不须要拦挡
@Configurationpublic class InterceperConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { //增加拦截器 InterceptorRegistration interceptorRegistration = registry.addInterceptor(new LogInterceptor() { }); //如下的门路不拦挡,多个门路用逗号分隔 interceptorRegistration.excludePathPatterns("/demo/test2"); //拦挡如下门路 interceptorRegistration.addPathPatterns("/**"); }}
好了,拦截器就做完了,so easy。上面咱们写个controller
来测试下吧!
@RestController@RequestMapping("/demo")public class DemoController { @GetMapping("test1") public String test1(){ System.out.println("rest.test1 is called"); return "test1"; } @GetMapping("test2") public String test2(){ System.out.println("rest.test2 is called"); return "test2"; } @GetMapping("test3") public String test3(@RequestParam("a")String a){ System.out.println("rest.test3 is called"); return "test3"; }}
测试的后果根本能够预期到
- demo/test1 和 demo/test3会被拦挡,进拦截器
- demo/test2 不会进拦截器
- demo/test3?a=1 这个申请会进拦截器,然而进不了controller。
过滤器
@WebFilter(urlPatterns = "/*", filterName = "LogFilter")public class LogFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("logfilter.init is called..."); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("filter中打印的申请参数:"); Enumeration<String> parameterNames = servletRequest.getParameterNames(); while (parameterNames.hasMoreElements()) { String key = parameterNames.nextElement(); String value = servletRequest.getParameter(key); System.out.println(key+"==>"+value); } long bgn = System.currentTimeMillis(); //肯定要调用链式调用传递,否则也进不了controller filterChain.doFilter(servletRequest,servletResponse); long end = System.currentTimeMillis(); System.out.println("filter中记录耗时:"+(end-bgn)+"ms"); } @Override public void destroy() { System.out.println("logfilter.destroy is called..."); }}
留神:@WebFilter
这个注解是Servlet3.0
的标准,并不是Spring boot
提供的。除了这个注解以外,咱们还需在配置类中加另外一个注解:@ServletComponetScan
,指定扫描的包。
总结
拦截器、过滤器执行程序,默认先执行过滤器,再执行拦截器。
如果过滤器有多个会依据过滤器的名词依照A-Z的排序先后执行。这是因为@WebFilter
这个注解不反对执行程序。当然你也能够通过写一个配置文件解决。
@Configurationpublic class WebConfig { @Bean public FilterRegistrationBean reqResFilter1() { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); LogFilter logFilter = new LogFilter(); filterRegistrationBean.setFilter(logFilter); filterRegistrationBean.addUrlPatterns("/demo/test1","/demo/test3");//配置过滤规定 filterRegistrationBean.addInitParameter("name","spingboot");//设置init参数 filterRegistrationBean.setName("logFilter");//设置过滤器名称 filterRegistrationBean.setOrder(2);//执行秩序 return filterRegistrationBean; } @Bean public FilterRegistrationBean reqResFilter() { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); Log1Filter log1Filter = new Log1Filter(); filterRegistrationBean.setFilter(log1Filter); filterRegistrationBean.addUrlPatterns("*");//配置过滤规定 filterRegistrationBean.setName("Log1Filter");//设置过滤器名称 filterRegistrationBean.setOrder(1);//执行秩序 return filterRegistrationBean; }}
更多java原创浏览:https://javawu.com/