(以下内容全部由外部资源总结)
Api的拦截:
一、自定义Filter(过滤器):
需要实现Filter接口(java的接口和spring无关)
这个接口有三个方法需要实现:
- init() //创建
- destroy() //销毁
- doFilter(ServletRequest request,ServletResponse response,FilterChain chain) //写自己的逻辑 ,要在方法doFilter()中加上:chain.doFilter(request,response) //表示请求下一个过滤器(过滤器链),最后还要注入spring容器,之后每一次接收请求都会走这个过滤器。
那么如何将第三方过滤器加入到系统过滤器链呢?
传统方式是在xml配置文件里配置,springboot中我们可以这样做:
图片中的 ”/*“ 代表再什么范围内起作用。
缺点:这是java的接口,在这个方法中,不能找到是控制器(controller)中的哪个方法来处理的。
二、如果想获取这些信息可以用Interceptor(拦截器)方式
先实现HandlerInterceptor接口,这个接口有三个方法:
boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handle)方法:该方法将在请求处理之前进行调用,只有该方法返回true,才会继续执行后续的Interceptor和Controller,当返回值为true 时就会继续调用下一个Interceptor的preHandle 方法,如果已经是最后一个Interceptor的时候就会是调用当前请求的Controller方法;
void postHandle (HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView)方法:该方法将在请求处理之后,DispatcherServlet进行视图返回渲染之前进行调用,可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作。如果抛出异常,那么这个方法不会被调用。
void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex)方法:这个方法最后无论如何都会被调用,该方法也是需要当前对应的Interceptor的preHandle方法的返回值为true时才会执行,该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。用于进行资源清理。这个方法可以用来处理代码中抛出的异常(但是要注意:异常只能被处理一次,如果异常在之前已经被处理了那么就收不到异常的信息了)。
利用这几个方法的第三个参数(Object handle)可以获取到bean的详细信息。
注意:拦截器会拦截所有控制器(controller)中的方法的吊用,无论是自己方法还是spring的方法。
三、Aspect(切面)
按照这个规则我们可以这样写
方法上的@Aspect注解可以用表达式来指定应用这个切面的范围,方法中的pjp参数就是被切入的方法信息,可以取到方法的参数、返回值等信息。
总结:
这三种方式各有各的特点,我们要根据需求决定使用哪一种。
最后附上一张过滤器、拦截器、切面等执行的顺序: