拦截器 过滤器

区别

参考

拦截器Interceptor和过滤器Filter的区别在于:
1、拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,就可以调用业务逻辑。
2、Filter的使用要依赖于Tomcat等容器,导致它只能在web程序中使用;Interceptor依赖Spring,可以使用在非web程序。
3、

访问流程:Tomcat——Filter——Servlet——Interceptor——Controller——Service——Mapper

拦截器Interceptor(两步)

基本使用

1、定义一个拦截器,实现HandlerInterceptor接口,实现HandlerInterceptor接口的三个方法:
preHandle() :这个方法将在请求处理之前进行调用。注意:如果该方法的返回值为false ,将视为当前请求结束,不仅自身的拦截器会失效,还会导致其他的拦截器也不再执行。
postHandle():只有在 preHandle() 方法返回值为true 时才会执行。会在Controller 中的方法调用之后,DispatcherServlet 返回渲染视图之前被调用。 有意思的是:postHandle() 方法被调用的顺序跟 preHandle() 是相反的,先声明的拦截器 preHandle() 方法先执行,而postHandle()方法反而会后执行。
afterCompletion():只有在 preHandle() 方法返回值为true 时才会执行。在整个请求结束之后, DispatcherServlet 渲染了对应的视图之后执行。

@Component
public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        System.out.println("Interceptor 前置");
        if(true){
        	return true;
        }else{//验证不通过使用PrintWriter返回
        	PrintWriter writer = null;
        	response.setCharacterEncoding("UTF-8");
        	response.setContentType("application/json; charset=utf-8");
        	try {
            	writer = response.getWriter();
            	Map<String, Object> result = new HashMap<>();
            	result.put("data", null);
            	writer.print(result);
        	} catch (IOException e){
            	LoggerUtil.logError(ECInterceptor.class, "拦截器输出流异常"+e);
        	} finally {
        		//一定要关闭
            	if(writer != null){
                	writer.close();
            	}
        	}
        }
    }

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

        System.out.println("Interceptor 处理中");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

        System.out.println("Interceptor 后置");
    }
}

2、创建一个配置类,将自定义好的拦截器处理类进行注册,并通过addPathPatterns、excludePathPatterns等属性设置需要拦截或需要排除的 URL。

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
        registry.addInterceptor(new MyInterceptor1()).addPathPatterns("/**");
    }
}

进阶使用

分析public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception的参数列表:
request:当前HTTP请求
response:当前HTTP相应
handler:SpringMVC处理器映射器将请求交给匹配的Handler处理,这个handler参数就是描述的处理请求的Handler。
这个handler对应的是本次Http访问的Controller的对应方法

	//先转为HandlerMethod之后,调用getMethod()获取具体处理请求的方法
	HandlerMethod handlerMethod = (HandlerMethod)handler;
    Method method = handlerMethod.getMethod();//获取到XXController类对应url的方法

**总结:**可以使用这种形式,对某些接口加上注解完成某些限制或增强。

过滤器Filter

基本使用

使用步骤:
1、实现Filter接口
2、实现init()、doFilter()、destroy()方法。其中doFilter()方法是干活的。

两种方式
1、案例033:注解方式
2、案例034:配置文件类

注:路径例如 /user/* 不能/user/**

示例:
注解方式:

@Component
@Order(1)
@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("MyFilter");
        // 要继续处理请求,必须添加 filterChain.doFilter()
        filterChain.doFilter(servletRequest,servletResponse);
    }
}

配置类方式:
定义MyFilter类实现Filter接口,重写三个方法之后:

@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean registerMyFilter(){
        FilterRegistrationBean<MyFilter> bean = new FilterRegistrationBean<>();
        bean.setOrder(1);
        bean.setFilter(new MyFilter());
        // 匹配"/hello/"下面的所有url
        bean.addUrlPatterns("/hello/*");
        return bean;
    }
    @Bean
    public FilterRegistrationBean registerMyAnotherFilter(){
        FilterRegistrationBean<MyAnotherFilter> bean = new FilterRegistrationBean<>();
        bean.setOrder(2);
        bean.setFilter(new MyAnotherFilter());
        // 匹配所有url
        bean.addUrlPatterns("/*");
        return bean;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值