SSM

SpringBoot/Spring-拦截机制

2019-07-29  本文已影响80人  小胖学编程

SpringBoot的拦截机制不是特有的,他和Spring是一致的,都可以使用下面三种技术来实现拦截机制:

本质上他们都是AOP的体现。

1. 过滤器和拦截器的区别

  1. 过滤器可以修改request(继承HttpServletRequestWrapper重新装饰request),而拦截器不能。
  2. 过滤器需要在Servlet容器中实现,而拦截器是在Spring容器下实现的。
  3. 拦截器可以调用IOC容器中的各种依赖,而过滤器不能。
  4. 过滤器只能在请求的前后使用,而拦截器可以具体到某个(Controller)方法。

过滤器就是筛选出想要的东西,比如request那部分数据。而拦截器在安全控制方面用的比较多,比如终止一些流程。

请求先走过滤器,再走拦截器!

Filter过滤器需要在web.xml中配置,依赖于Servlet;
Interceptor拦截器需要在SpringMvc中配置,依赖于框架;

2. 过滤器详解

过滤器在过滤器链中的顺序与它在web.xml中的配置有关。在doFilter()方法中,chain.doFilter()前一般对request执行过滤操作,chain.doFilter一般对response执行过滤操作。

Filter的生命周期

  1. Filter的创建和销毁由web服务器负责,web应用启动的时候,web服务器将创建Filter实例,并调用其init方法,完成对象的初始化功能,filter只会创建一次,init方法也只会执行一次。

  2. web容器调用destroy方法销毁Filter。destroy方法在Filter的生命周期中仅执行一次。在destroy方法中,可以释放过滤器使用的资源。

FilterConfig接口

用户在配置filter时,可以使用为filter配置一些初始化参数,当web容器实例化Filter对象,调用其init方法时,会把封装了 filter初始化参数的filterConfig对象传递进来。因此开发人员在编写filter时,通过filterConfig对象的方法,就可获得:

  1. String getFilterName():得到filter的名称。
  2. String getInitParameter(String name): 返回在部署描述中指定名称的初始化参数的值。如果不存在返回null。
  3. Enumeration getInitParameterNames():返回过滤器的所有初始化参数的名字的枚举集合。
  4. public ServletContext getServletContext():返回Servlet上下文对象的引用。

CORS跨域资源共享过滤器:

public class CORSFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Methods", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with,content-type");
        chain.doFilter(req, res);
    }

    public void init(FilterConfig filterConfig) {
    }

    public void destroy() {
    }

}

3. 拦截器

@Component
public class LogInterceptor implements HandlerInterceptor {

    private final static Logger logger = LoggerFactory.getLogger(LogInterceptor.class);

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        
    }
}
  1. preHandle在被拦截方法执行之前回调。
  2. postHandle方法在被拦截方法执行之后,跳转页面之前回调。
  3. afterCompletion方法在跳转页面之后执行。

3. 切面拦截

AOP切面编程需要引入的jar包

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

AOP切面通知的执行顺序:

进入环绕通知
前置通知
Object result=(boolean)jointPoint.proceed();  //执行该方法
退出环绕通知
后置通知
返回通知
@Component
@Aspect
public class ServiceAspect {

    private static final Logger logger = LoggerFactory.getLogger(ServiceAspect.class);

    //定义切点com.tellme.controller.PersonController
    private final String POINT_CUT = "execution(public * com.tellme.controller.*.*(..))";

    @Pointcut(POINT_CUT)
    public void pointCut() {
    }

    @Before(value = "pointCut()")
    public void before(JoinPoint joinPoint) {
        logger.info("前置通知");
    }
}

文章参考

spring boot入门(七) springboot的拦截器Interceptor。最完整、简单易懂、详细的spring boot教程。

Java过滤器Filter使用详解

Springboot(二十一)@Aspect 切面注解使用

上一篇下一篇

猜你喜欢

热点阅读