JavaWeb——过滤器Filter和拦截器Interceptor

过滤器Filter

简介: 

Filter会将浏览器对服务器资源的请求先统一拦截,要通过Fliter才能访问到对应资源,访问操作结束后会回到过滤器再响应给浏览器。

入门案例

流程: 

 定义好一个Fliter后要加上一个@WebFilter注解才会生效,同时,还要指定该过滤器要拦截什么样的请求,urlPatterns="/*"表示拦截所有请求。同时还要在项目的启动类当中加上一个@ServletComponentScan注解,表示支持Servlet组件,因为Filter是javaweb的三大组件之一,不是springboot提供

新建一个Filter包下的一个DemoFilter类实现Filter接口

其中要实现三个方法,init()和destory()方法因为不常用,在Filter接口中对于这两个方法已经有了默认实现,可以不用实现init()和destory方法。

@WebFilter(urlPatterns = "/*")
public class DemoFilter implements Filter {
    //只调用一次
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
       // Filter.super.init(filterConfig);
        System.out.println("init方法");
    }


    @Override //拦截到请求之后调用,调用多次
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("拦截到了请求");
 //放行
 //      filterChain.doFilter(servletRequest,servletResponse);
    }
    //只调用一次
    @Override
    public void destroy() {
       // Filter.super.destroy();
        System.out.println("destroy方法");
    }
}

在项目启动类当中

项目结构如下 

 启动项目后控制台输出如下

在前端页面中进行请求后控制台输出如下

 

并且前端页面在等待过滤器返回的数据

 为了让前端页面正常展示,现在要进行放行,使用Filter提供的FilterChain,直接调用它下面的doFilter方法,需要的请求对象ServletRequest对象和响应对象都已经作为形参传了进来,所以可以直接用。

 @Override //拦截到请求之后调用,调用多次
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("拦截到了请求");
        //放行
        filterChain.doFilter(servletRequest,servletResponse);
    }

在停止项目时可以看见Filter的销毁方法的执行

重新启动项目之后可以看见请求放行之后正常显示了出来,

放行之后就会去到Controller当中执行对应操作

 详解(执行流程,拦截路径,过滤器链)

执行流程

放行前可以执行一段逻辑,放行之后也可以执行一段逻辑

Filter当中 

    @Override //拦截到请求之后调用,调用多次
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("拦截到了请求...放行前逻辑");
        //放行
        filterChain.doFilter(servletRequest,servletResponse);

        System.out.println("拦截到了请求...放行后逻辑");
    }

postman测试

在前端页面进行登录操作之后,后端控制台输出如下,放行前后的操作都有执行 

Filter拦截路径

拦截的不同种类

Filter过滤器链 

有多个过滤器先后执行时需要在所以的过滤器都放行后才能访问对应资源。

在Filter包下新建一个Demo1Filter如下配置

@WebFilter(urlPatterns = "/*")
public class Demo1Filter implements Filter {

    @Override //拦截到请求之后调用,调用多次
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("1拦截到了请求...放行前逻辑");
        //放行
        filterChain.doFilter(servletRequest,servletResponse);

        System.out.println("1拦截到了请求...放行后逻辑");
    }
}

上面的FilterChain就是一个过滤器列,doFilter方法会放行到下一个过滤器,如果当前是最后一个过滤器就会放行到Web资源当中。此处过滤器的先后顺序是由过滤器类在包里面的先后顺序所决定的,如下就是不同的顺序时的输出。

 

 拦截器Interceptor

简介&: 

流程:

 

 上面的上个方法都有默认实现,这里根据需要重写。

其中preHandle在Controller之前执行,postHandle在Controller之后执行

其次还要注册配置拦截器 ,其中从写的方法里面的/**表示拦截所有。

新建一个 interceptor包下的LoginCheckInterceptor类实现接口

实现完后要将其交给IOC容器管理

@Component
public class LoginCheckInterceptor implements HandlerInterceptor {
    @Override //在目标资源方法前运行,返回true:放行,返回false:不放行
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle...");
        return true;
    }

    @Override //目标资源方法运行后运行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle...");
    }

    @Override //试图渲染完毕后运行,最后运行
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion...");
    }
}

新建一个Config包下的WebConfig类

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired //获取到拦截器的bean对象
    private LoginCheckInterceptor loginCheckInterceptor;


    @Override  //用于注册拦截器
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**");
    }
}

实现并注册好拦截器之后就可以在postman中进行测试 

 

在后台中看见拦截器中的三个方法都有运行输出 

设置返回值为 false时就不会放行 

 

详解(拦截路径,执行流程) 

拦截路径

比如登录页面的请求就是不需要拦截的。

常见的拦截配置

 在拦截器配置中修改如下,放行login请求

    @Override  //用于注册拦截器
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**").excludePathPatterns("/login");
    }

成功登录

执行流程 

浏览器发出的请求会先被过滤器拦截,然后进入到spring环境,tomcat不识别controller,但是识别servlet,spring的web环境提供了一个非常核心的servlet——DispatchServlet。由DispatchServlet转给Controller,在这之前会先被拦截器拦截执行preHandle方法,根据其返回值决定是否执行Controller方法。

POstman测试 

使用Filter和interceptor进行测试,发送查询所有部门的请求

服务器控制台输出如下

可以看出,就和栈一样,后进的反而先出了 

 

过滤器和拦截器的区别 

 

 

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值