共计 4223 个字符,预计需要花费 11 分钟才能阅读完成。
理论我的项目开发过程中,必定有这样的需要:
- 记录每个 rest 申请消耗的工夫,入参,出参
- 某些申请须要判断是否有权限,某些申请是不须要权限也能够运行的
这个需要太广泛了。明天咱们就一起来学习这个需要的两种实现形式:
- 拦截器
- 过滤器
拦截器
话不多说,咱们上代码,新建日志拦截器:
@Component
public 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
哪些门路须要拦挡,哪些门路不须要拦挡
@Configuration
public 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
这个注解不反对执行程序。当然你也能够通过写一个配置文件解决。
@Configuration
public 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/
正文完