Spring拦截器&过滤器

一、拦截器 Interceptor

  实现HandlerInterceptor接口,并重写以下方法

    preHandle(..):在实际处理程序运行之前

    postHandle(..): 处理程序运行后

      afterCompletion(..): 完成请求后

  preHandle方法返回一个布尔值,可以使用此方法中断或继续执行链的处理。当此方法返回true时,处理程序执行链继续;当返回false时,DispatcherServlet 假定拦截器本身已经处理了请求(并且,例如,呈现了适当的视图)并且不会继续执行其他拦截器和执行链中的实际处理程序

 

  1、定义拦截器

public class MyInterceptor implements HandlerInterceptor {

    /**
     * controller执行前调用此方法
     * 返回true表示继续执行,返回false中止执行
     * 这里可以加入登录校验、权限拦截等
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("interceptor preHandle");
        return true;
    }

    /**
     * controller执行后但未返回视图前调用此方法
     * 这里可在返回用户前对模型数据进行加工处理,比如这里加入公用信息以便页面显示(比如:菜单导航)
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("interceptor postHandle");
        // TODO
    }

    /**
     * controller执行后但未返回视图前调用此方法
     * 这里可在返回用户前对模型数据进行加工处理,比如这里加入公用信息以便页面显示(比如:菜单导航)
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("interceptor afterCompletion");
        // TODO
    }
}

  2、注册拦截器

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LocaleChangeInterceptor());
        registry.addInterceptor(new ThemeChangeInterceptor()).addPathPatterns("/**").excludePathPatterns("/admin/**");
        registry.addInterceptor(new SecurityInterceptor()).addPathPatterns("/secure/*");
    }
}

    xml配置方式:

<mvc:interceptors>
    <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <mvc:exclude-mapping path="/admin/**"/>
        <bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor"/>
    </mvc:interceptor>
    <mvc:interceptor>
        <mvc:mapping path="/secure/*"/>
        <bean class="org.example.SecurityInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

  

 

  注意:在springboot项目中不必使用@EnableWebMvc 注解,因为@EnableWebMvc 注解会导致WebMvcAutoConfiguration失效,也就是Springboot的自动配置机制失效

  原因:

  @EnableWebMvc 注解会通过 import 引入 @Configuration 注解的类 DelegatingWebMvcConfiguration,然后 DelegatingWebMvcConfiguration 类又继承了 WebMvcConfigurationSupport 类。

  最后,在 WebMvcAutoConfiguration 类中有一个 @ConditionalOnMissingBean(WebMvcConfigurationSupport.class) 注解,其意义是,当没有 WebMvcConfigurationSupport 类时,WebMvcAutoConfiguration(即 SpringMvc 的自动配置类)才会生效。

  

  因此,继承 WebMvcConfigurationSupport 会导致 SpringMvc 的自动配置类失效

 

 

二、过滤器 Filter

  过滤器能起到拦截请求并做出相应动作。比如可以进行登录过滤等

  实现方式:实现Filter接口、实现AbstractFilter抽象类

  1、定义过滤器(实现Filter接口)

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import java.io.IOException;

@WebFilter(filterName = "myFilter", urlPatterns = "/*", initParams = {
        @WebInitParam(name = "name", value = "yang")})
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("filter init");
        String name = filterConfig.getInitParameter("name");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        System.out.println("filter doFilter");
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        System.out.println("filter destroy");
    }
}

  2、注册Filter

    有以下两种方式:

      ①:在Filter上添加@Component注解

      ②:Spring启动类上添加 @ServletComponentScan注解

 

  Springboot中注册拦截器:

@Configuration
public class FilterConfig {

    @Bean
    FilterRegistrationBean<Filter01> filter01FilterRegistrationBean() {
        FilterRegistrationBean<Filter01> bean = new FilterRegistrationBean<>();
        bean.setFilter(new Filter01());
        bean.setOrder(99);
        bean.setUrlPatterns(Arrays.asList("/*"));
        return bean;
    }

}

 

 

三、Interceptor、Filter、Aop执行顺序  

filter init
filter doFilter
interceptor preHandle
aop start
hello controller
aop end
interceptor postHandle
interceptor afterCompletion

 

 

 

 

 

 

END.

posted @ 2022-01-13 16:59  杨岂  阅读(823)  评论(0编辑  收藏  举报