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

Posted 北岭山脚鼠鼠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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进行测试,发送查询所有部门的请求

服务器控制台输出如下

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

 

过滤器和拦截器的区别 

 

 

javaweb中怎么添加过滤器

参考技术A web.xml中配置,如filter>
<!-- Filter的名字 -->
<filter-name>log</filter-name>
<!-- Filter的实现类 -->
<filter-class>lee.LogFilter</filter-class>
</filter>
<!-- 定义Filter拦截的URL地址 -->
<filter-mapping>
<!-- Filter的名字 -->
<filter-name>log</filter-name>
<!-- Filter负责拦截的URL 全部以/的请求,如果<url-pattern>/*.action </>,将会以拦截*.action的请求-->
<url-pattern>/*</url-pattern>
</filter-mapping>本回答被提问者采纳

以上是关于JavaWeb——过滤器Filter和拦截器Interceptor的主要内容,如果未能解决你的问题,请参考以下文章

java web 过滤器跟拦截器的区别和使用

javaweb过滤器请求有先后顺序导致静态资源加载不出来

JavaWeb--Filter(过滤器)学习

JavaWeb 之 Filter:过滤器

[JavaWeb] Servlet Filter

Filter过滤器-JavaWeb三大组件之一