精华内容
下载资源
问答
  • 2022-05-31 13:20:08

    过滤器和拦截器的区别?

    1. 拦截器是基于java的反射机制,而过滤器基于函数回调。
    2. 过滤器依赖于servlet容器,拦截器不依赖于servlet容器。
    3. 拦截器只能对action请求起作用,而过滤器几乎对所有的请求都起作用。
    4. 拦截器可以访问action上下文,值栈里的对象,而过滤器不能。
    5. 在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
    6. 拦截器可以获取IOC容器中的各个bean,而过滤器就不行,(在拦截器里注入一个service,可以调用业务逻辑)。
    7. 过滤器是在请求进入容器后,但进入servlert前进行预处理的。响应请求也是,在servlet处理结束后,返回给客户端前触发。而拦截器提供了三个方法支持(1)preHandle:预处理回调方法,实现处理器的预处理(如登录检查),第三个参数为响应的处理器(如我们上一章的Controller实现); 返回值:true表示继续流程(如调用下一个拦截器或处理器);false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应;postHandle:后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null。
      afterCompletion:整个请求处理完毕回调方法,即在视图渲染完毕时回调,如性能监控中我们可以在此记录结束时间并输出消耗时间,还可以进行一些资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中preHandle返回true的拦截器的afterCompletion。

    从广义上来分析二者区别:

    1. 使用范围不同:Filter是Servlet规范规定的,只能用于web程序中。而拦截器既可以用于web程序,也可以用于Application、swing程序中。
    2. 规范不同:Filter是在servlet规范中定义的,是Servlet容器支持的,而拦截器是在spring容器内的,是spring框架支持的。
    3. 使用的资源不同:同其他的代码块一样,拦截器也是一个spring的组件,归spring管理,配置在spring文件中,因此能使用spring里的任何资源,独享。例如service对象、数据源、事务管理等,通过IOC注入到拦截器即可;而Filter不能。
    4. 深度不同:Filter只在Servlet前后起作用。而拦截器能深入到方法前后、异常抛出前后等。因此拦截器的使用灵活性更大。所以在Spring为基础的构架的程序中,优先使用拦截器。

    💥《核心技术系列专栏汇总》💥

    需要 大厂面试题简历模版电子书学习资料 等关注👇【公众号】👇回复「 1024 」即可。

    更多相关内容
  • 主要介绍了通过实例解析java过滤器和拦截器的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • Java过滤器拦截器的区别1. 过滤器与拦截器概述1.1 过滤器 Filter1.2 拦截器 interceptor2. 过滤器与拦截器区别3. 过滤器与拦截器实现3.1 过滤器(Filter)3.2 拦截器 (Interceptor)3.3 拦截器WebMvc配置3.4 切片...

    1. 过滤器与拦截器概述

    1.1 过滤器 Filter

    依赖于servlet容器,实现基于函数回调,可以对几乎所有请求进行过滤,
    但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的是用来做一些过滤操作,
    获取我们想要获取的数据,过滤器一般用于登录权限验证、资源访问权限控制、敏感词汇过滤、
    字符编码转换等等操作,便于代码重用,不必每个servlet中进行冗余操作。
    
    Java中的Filter并不是一个标准的Servlet ,它不能处理用户请求,也不能对客户端生成响应。 
    主要用于对HttpServletRequest 进行预处理,也可以对HttpServletResponse 进行后处理,是个典型的处理链。
    完整的流程是:Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,
    最后Filter再对服务器响应进行后处理。在HttpServletRequest 到达Servlet 之前,拦截客户的HttpServletRequest。
    根据需要检查HttpServletRequest ,也可以修改HttpServletRequest 头和数据。在响应到达客户端之前,拦截HttpServletResponse。根据需要检查HttpServletResponse ,可以修改HttpServletResponse 头和数据。
    
    Filter随web应用的启动而启动,只初始化一次,随web应用的停止而销毁。
    1.启动服务器时加载过滤器的实例,并调用init()方法来初始化实例;
    2.每一次请求时都只调用方法doFilter()进行处理;
    3.停止服务器时调用destroy()方法,销毁实例。
    

    1.2 拦截器 interceptor

    依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。
    在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。
    由于拦截器是基于web框架的调用,拦截器可以调用IOC容器中的各种依赖,而过滤器不能,
    因此可以使用Spring的依赖注入进行一些业务操作,
    同时一个拦截器实例在一个controller生命周期之内可以多次调用。
    但是缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理。
    
    spring mvc中的Interceptor可以理解为是Spring MVC框架对AOP的一种实现方式。
    一般简单的功能又是通用的,每个请求都要去处理的,比如判断token是否失效可以使用spring mvc的HanlderInterceptor, 
    复杂的,比如缓存,需要高度自定义的就用spring aop。一般来说service层更多用spring aop,
    controller层有必要用到request和response的时候,可以用拦截器。
    
    spring mvc中的Interceptor拦截请求是通过HandlerInterceptor来实现的。
    所以HandlerInteceptor拦截器只有在Spring Web MVC环境下才能使用。
    在SpringMVC中定义一个拦截器主要有两种方式,第一种方式是要实现Spring的HandlerInterceptor接口,
    或者是其它实现了HandlerInterceptor接口的类,比如HandlerInterceptorAdapter。
    第二种方式是实现WebRequestInterceptor接口,或者其它实现了WebRequestInterceptor的类。
    
    HandlerInterceptor接口定义方法preHandle, postHandle, 和afterCompletion:
    preHandle(进入 Handler方法之前执行):预处理回调方法,实现处理器的预处理(如登录检查),返回值:true表示继续流程
    (如调用下一个拦截器或处理器),false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,
    此时我们需要通过response来产生响应。
    postHandle(进入handler方法之后,返回modelAndView之前):后处理回调方法,
    实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView
    (模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null。
    
    afterCompletion(执行Handler完成执行此方法):整个请求处理完毕回调方法,即在视图渲染完毕时回调。
    该方法也是需要当前对应的Interceptor 的preHandle方法的返回值为true时才会执行。
    这个方法的主要作用是用于进行资源清理工作的,如性能监控中我们可以在此记录结束时间并输出消耗时间。
    

    2. 过滤器与拦截器区别

    1、实现原理不同
    过滤器和拦截器 底层实现方式大不相同,过滤器是基于函数回调的,拦截器则是基于Java的反射机制(动态代理)实现的。

    2、使用范围不同
    我们看到过滤器 实现的是 javax.servlet.Filter 接口,而这个接口是在Servlet规范中定义的,也就是说过滤器Filter 的使用要依赖于Tomcat等容器,导致它只能在web程序中使用。
    而拦截器(Interceptor) 它是一个Spring组件,并由Spring容器管理,并不依赖Tomcat等容器,是可以单独使用的。不仅能应用在web程序中,也可以用于Application、Swing等程序中。

    3、触发时机不同
    过滤器 和 拦截器的触发时机也不同,我们看下边这张图。
    过滤器Filter是在请求进入容器后,但在进入servlet之前进行预处理,请求结束是在servlet处理完以后。
    拦截器 Interceptor 是在请求进入servlet后,在进入Controller之前进行预处理的,Controller 中渲染了对应的视图之后请求结束。
    在这里插入图片描述
    4、拦截的请求范围不同
    过滤器的init()方法,随着容器的启动进行了初始化。
    执行顺序 :Filter 处理中 -> Interceptor 前置 -> 我是controller -> Interceptor 处理中 -> Interceptor 处理后
    过滤器Filter执行了两次,拦截器Interceptor只执行了一次。这是因为过滤器几乎可以对所有进入容器的请求起作用,而拦截器只会对Controller中请求或访问static目录下的资源请求起作用。

    5、注入Bean情况不同
    在拦截器与过滤器中分别注入service进行逻辑处理,拦截器会空指针:
    原因:拦截器加载的时间点在springcontext之前,而Bean又是由spring进行管理。
    解决方案也很简单,我们在注册拦截器之前,先将Interceptor 手动进行注入。「注意」:在registry.addInterceptor()注册的是getMyInterceptor() 实例。

    6、控制执行顺序不同
    实际开发过程中,会出现多个过滤器或拦截器同时存在的情况,不过,有时我们希望某个过滤器或拦截器能优先执行,就涉及到它们的执行顺序。
    过滤器用@Order注解控制执行顺序,通过@Order控制过滤器的级别,值越小级别越高越先执行。
    拦截器默认的执行顺序,就是它的注册顺序,也可以通过Order手动设置控制,值越小越先执行。

    注意:
    先声明的拦截器 preHandle() 方法先执行,而postHandle()方法反而会后执行。
    postHandle() 方法被调用的顺序跟 preHandle() 居然是相反的!如果实际开发中严格要求执行顺序,那就需要特别注意这一点。

    原因:
    得到答案就只能看源码了,我们要知道controller 中所有的请求都要经过核心组件DispatcherServlet路由,都会执行它的 doDispatch() 方法,而拦截器postHandle()、preHandle()方法便是在其中调用的。
    看看两个方法applyPreHandle()、applyPostHandle()具体是如何被调用的,就明白为什么postHandle()、preHandle() 执行顺序是相反的了。
    发现两个方法中在调用拦截器数组 HandlerInterceptor[] 时,循环的顺序竟然是相反的。。。,导致postHandle()、preHandle() 方法执行的顺序相反。

    3. 过滤器与拦截器实现

    3.1 过滤器(Filter)

    package com.example.category.aop;
    
    import lombok.extern.slf4j.Slf4j;
    
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import java.io.IOException;
    
    /**
     * 过滤器(Filter)
     * 注意:
     * init与destroy方法不是所必须实现的,可以选择或者手动实现
     * 启动类如果不加@ServletComponentScan就算这个类和运行类平级或者子级也不会被扫描上
     * filterName可以省略不能重复@WebFilter(filterName = "myFilterTwo"),
     *
     * @author zrj
     * @since 2021/8/17
     **/
    @Slf4j
    @WebFilter(filterName = "myFilter", urlPatterns = "/*")
    public class MyFilter implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            log.info("[过滤器]过滤器初始化");
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            log.info("[过滤器]过滤器执行过滤操作");
            //放行
            filterChain.doFilter(servletRequest, servletResponse);
        }
    
        @Override
        public void destroy() {
            log.info("[过滤器]过滤器销毁");
        }
    }
    
    

    3.2 拦截器 (Interceptor)

    package com.example.category.aop;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.lang.Nullable;
    import org.springframework.stereotype.Component;
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * 拦截器 (Interceptor)
     * HandlerInterceptor:springMVC框架拦截器
     * 必须在WebMvc配置以后生效
     *
     * @author zrj
     * @since 2021/8/17
     **/
    @Slf4j
    @Component
    public class MyInterceptor implements HandlerInterceptor {
        /**
         * 前置拦截器
         * 如果该方法的返回值为false ,将视为当前请求结束,不仅自身的拦截器会失效,还会导致其他的拦截器也不再执行。
         */
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            log.info("[拦截器]前置拦截器preHandle");
            return true;
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
            log.info("[拦截器]处理拦截器postHandle");
        }
    
        /**
         * 后置拦截器
         * afterCompletion:只有在 preHandle() 方法返回值为true 时才会执行
         */
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
            log.info("[拦截器]后置拦截器afterCompletion");
        }
    }
    
    

    3.3 拦截器WebMvc配置

    package com.example.category.config;
    
    import com.example.category.aop.MyInterceptor;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    import javax.annotation.Resource;
    
    /**
     * WebMvc配置
     * 配置自定义拦截器
     *
     * @author zrj
     * @since 2021/8/17
     **/
    @Configuration
    public class CommonWebConfig implements WebMvcConfigurer {
    
        @Resource
        private MyInterceptor myInterceptor;
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(myInterceptor);
        }
    
    }
    
    

    3.4 切片(Aspect)

    package com.example.category.aop;
    
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import lombok.extern.slf4j.Slf4j;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.*;
    import org.springframework.stereotype.Component;
    
    import java.util.Arrays;
    
    /**
     * 切片(Aspect)
     *
     * @author zrj
     * @since 2021/8/17
     **/
    @Slf4j
    @Aspect
    @Component
    public class MyAspect {
        // 定义切点位置
        private final String POINT_CUT = "execution(* com.example.category.controller..*.*(..))";
        private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
    
        /**
         * 定义切点位置:下面如果你在SSM中用AOP,在xml中配的就是下面
         */
        @Pointcut(POINT_CUT)
        public void pointCut() {
        }
    
        /**
         * 前置通知
         *
         * @param joinPoint 连接点
         * @throws Throwable
         */
        @Before("pointCut()")
        public void before(JoinPoint joinPoint) throws Throwable {
            log.info("[切片]前置通知@Before");
            //获取目标方法参数信息
            Object[] args = joinPoint.getArgs();
            Arrays.stream(args).forEach(arg -> {
                try {
                    log.info(OBJECT_MAPPER.writeValueAsString(arg));
                } catch (JsonProcessingException e) {
                    log.info(arg.toString());
                }
            });
        }
    
        /**
         * 后置返回通知
         * 如果第一个参数为JoinPoint,则第二个参数为返回值的信息
         * 如果第一个参数不为JoinPoint,则第一个参数为returning中对应的参数
         * returning:限定了只有目标方法返回值与通知方法参数类型匹配时才能执行后置返回通知,否则不执行,
         * 参数为Object类型将匹配任何目标返回值
         */
        @AfterReturning(value = POINT_CUT, returning = "result")
        public void doAfterReturningAdvice1(JoinPoint joinPoint, Object result) {
            log.info("[切片]后置返回通知@AfterReturning,第一个的返回值:" + result);
        }
    
        @AfterReturning(value = POINT_CUT, returning = "result", argNames = "result")
        public void doAfterReturningAdvice2(String result) {
            log.info("[切片]后置返回通知@AfterReturning,第二个的返回值:" + result);
        }
    
        /**
         * 后置异常通知
         * 定义一个名字,该名字用于匹配通知实现方法的一个参数名,当目标方法抛出异常返回后,将把目标方法抛出的异常传给通知方法;
         * throwing:限定了只有目标方法抛出的异常与通知方法相应参数异常类型时才能执行后置异常通知,否则不执行,
         * 对于throwing对应的通知方法参数为Throwable类型将匹配任何异常。
         *
         * @param joinPoint 连接点
         * @param exception 异常
         */
        @AfterThrowing(value = POINT_CUT, throwing = "exception")
        public void doAfterThrowingAdvice(JoinPoint joinPoint, Throwable exception) {
            log.info("[切片]后置异常通知@AfterThrowing");
            log.info(joinPoint.getSignature().getName());
            if (exception instanceof NullPointerException) {
                log.info("发生了空指针异常!!!!!");
            }
        }
    
        /**
         * 后置通知
         *
         * @param joinPoint 连接点
         * @return void
         */
        @After(value = POINT_CUT)
        public void doAfterAdvice(JoinPoint joinPoint) {
            log.info("[切片]后置通知@After");
        }
    
        /**
         * 环绕通知:
         * 注意:Spring AOP的环绕通知会影响到AfterThrowing通知的运行,不要同时使用
         * 环绕通知非常强大,可以决定目标方法是否执行,什么时候执行,执行时是否需要替换方法参数,执行完毕是否需要替换返回值。
         * 环绕通知第一个参数必须是org.aspectj.lang.ProceedingJoinPoint类型
         */
        @Around(value = POINT_CUT)
        public Object doAroundAdvice(ProceedingJoinPoint proceedingJoinPoint) {
            log.info("[切片]环绕通知@Around开始," + proceedingJoinPoint.getSignature().toString());
            Object obj = null;
            try {
                obj = proceedingJoinPoint.proceed(); //可以加参数
                log.info("[切片]环绕通知@Around执行" + obj.toString());
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
            log.info("[切片]环绕通知@Around结束");
            return obj;
        }
    
    }
    

    4. 过滤器与拦截器执行顺序验证

    -> 过滤器doFilter -> 前置拦截器preHandle
    -> 环绕通知@Around开始 -> 前置通知@Before
    -> UserController
    -> 后置返回通知@AfterReturning -> 后置通知@After
    -> 环绕通知@Around执行 ->环绕通知@Around结束
    -> 处理拦截器postHandle -> 后置拦截器afterCompletion

    在这里插入图片描述

    展开全文
  • Java过滤器拦截器

    2022-05-08 16:01:52
    自JavaWeb中的过滤器,到Spring MVC中新增了拦截器,目的也是为了分离前后台。 对于二者的理解: 过滤器(FIlter):过滤器实际上是对一些web资源进行拦截 ,做一些处理后再交给下一个Servlet或者过滤器处理,它...

    在基于SSM框架的项目实战中,不管是写一个什么项目,前后台的分离是必不可少的。自JavaWeb中的过滤器,到Spring MVC中新增了拦截器,目的也是为了分离前后台。

    对于二者的理解:

    过滤器(FIlter):过滤器实际上是对一些web资源进行拦截 ,做一些处理后再交给下一个Servlet或者过滤器处理,它通常是用来拦截request进行处理的,也可以对返回的response进行拦截处理。

    拦截器(Intercepter):拦截器主要是用于拦截用户请求并做相应的处理,通常应用在权限验证、记录请求信息的日志、判断用户是否登录等等。

    二者的使用:(实现拦截后台)

    过滤器(FIlter):过滤器是实现了javax.servlet下的Filter接口,重写Filter中的三个方法:初始化init,过滤doFIlter,销毁destroy,其中doFilter()方法是去实现过滤相关内容的方法。

    import javax.servlet.*;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;
    
    public class ManagerFilter implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("初始化过滤器");
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            HttpServletRequest req= (HttpServletRequest) request;
            HttpServletResponse resp= (HttpServletResponse) response;
            HttpSession session = req.getSession();
            Integer status = (Integer) session.getAttribute("status");
            System.out.println(status);
            if (session.getAttribute("status") == null || (Integer) session.getAttribute("status") != 3) {
                req.setAttribute("meg", "你没有权限访问后台!");
                System.out.println("过滤器拦截--------");
                resp.sendRedirect("/MusicWebSite/index.html");
            } else {
                System.out.println("过滤器放行------------------------");
                chain.doFilter(req,resp);
            }
        }
    
        @Override
        public void destroy() {
            System.out.println("过滤器销毁");
        }
    }

    当然,过滤器的配置配置也是必不可少的,而过滤器主要是过滤页面的,就需要在web.xml中进行相关配置。 

        <filter>
            <filter-name>ManagerFilter</filter-name>
            <filter-class>project.filter.ManagerFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>ManagerFilter</filter-name>
            <url-pattern>/html/manager.html</url-pattern>
        </filter-mapping>

    拦截器(Intercepter):而定义一个拦截器,一般可以通过实现HandlerInterceptor接口或者继承HandlerInterceptor接口的实现类定义,还有一种已经过时的方法是通过WebRequestInterceptor接口或者继承WebRequestInterceptor接口的实现类定义,拦截器中的三个方法:

    preHandle:控制器方法执行之前执行preHandle(),其boolean类型的返回值表示是否拦截或放行,返回true为放行,即调用控制器方法;返回false表示拦截,即不调用控制器方法

    postHandle:控制器方法执行之后执行postHandle()

    afterComplation:处理完视图和模型数据,渲染视图完毕之后执行afterComplation()

    
    
    import org.springframework.stereotype.Component;
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    
    public class ManagerInterceptor extends HttpServlet implements HandlerInterceptor {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            HttpSession session = request.getSession();
            Integer status = (Integer) session.getAttribute("status");
            if (session.getAttribute("status") == null || (Integer) session.getAttribute("status") != 3) {
                request.setAttribute("meg", "你没有权限访问后台!");
                System.out.println("拦截器拦截--------");
                response.sendRedirect("/index.html");
                return false;
            } else {
                System.out.println("拦截器放行------------------------");
                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 {
         
        }
    }
    
    
    
         <mvc:interceptors>
            <mvc:interceptor>
                <mvc:mapping path="/manager/**"/>
                <bean class="project.interceptor.ManagerInterceptor"></bean>
            </mvc:interceptor>
        </mvc:interceptors>

    其中mvc:mapping是你需要拦截的controller的url,如果你不需要排除一些特定的url,就需要使用mvc:exclude-mapping属性。

    展开全文
  • 1.什么是拦截器? (1)在AOP中用于在某个方法或字段被访问之前,进行拦截然后再之前货之后加入某些操作。拦截是AOP的一种实现策略。 (2)拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者定义一个...

    一.简介

    1.什么是拦截器?
    (1)在AOP中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。拦截是AOP的一种实现策略。

    (2)拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者定义一个action前后执行的代码,也可以在一个action执行阻止其执行,同时也是提供了一种可以提取action可重用部分的方式。

    (3)实现原理:大部分是通过代理的方式来调用的。

    (4)自定义拦截器步骤:
    【1】自定义一个实现了Interceptor接口的类,或者继承抽象类AbstractInterceptor。
    【2】在配置文件中注册定义的拦截器。
    【3】在需要使用Action中引入定义的拦截器,为了方便也可以把拦截器定义为默认的拦截器。所有的Action都会被这个拦截器拦截

    2.什么是过滤器?
    (1)过滤器是一个程序,他先于与之相关的servlet或jsp,也可以运行在服务器上。过滤器可附加到一个或多个servlet或jsp页面上,并且可以检查进入这些资源的请求信息。

    (2)以常规的方式调用资源

    (3)利用修改过的请求信息调用资源

    (4)调用资源,但在发送响应到客户机前对其进行修改

    (5)阻止该资源调用,代之以转到其他的资源,返回一个特定的状态代码或生成替换输出。

    (6)过滤器的基本原理:在Servlet作为过滤器使用时,他可以对客户的请求进行处理。处理完成后,他会交给下一个过滤器处理,这样,客户的请求在过滤器链中逐个处理,直到请求发送到目标为止。

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

    (1)使用范围和规范不同
    【1】filter是servlet规范规定的,只能用在web程序中.
    【2】拦截器既可以用在web程序中, 也可以用于application, swing程序中, 是Spring容器内的, 是Spring框架支持的

    (2)触发时机不同
    顺序: Filter–>Servlet–>Interceptor–>Controller
    过滤器是在请求进入容器后,而请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前过滤器处理。请求在servlet之前,响应在servlet处理完之后。
    拦截器是方法到达Controller层之前生效的

    (3)过滤器的实现基于回调函数。而拦截器(代理模式)的实现基于反射,代理分静态代理和动态代理,动态代理是拦截器的简单实现

    何时使用拦截器?何时使用过滤器?
    【1】如果是非spring项目,那么拦截器不能用,只能使用过滤器。
    【2】如果是处理controller前后,既可以使用拦截器也可以使用过滤器。
    【3】如果是处理dispaterServlet前后,只能使用过滤器。

    (4)在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
    (5)拦截器可以访问action上下文、值,栈里的对象,而过滤器不能访问。
    (6)拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
    (7)拦截器可以获取IOC容器中的各个bean,而过滤器就不行,在拦截器里注入一个service,可以调用业务逻辑。

    过滤器(Filter):所谓过滤器顾名思义是用来过滤的,Java的过滤器能够为我们提供系统级别的过滤,也就是说,能过滤所有的web请求,这一点,是拦截器无法做到的。在Java Web中,你传入request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的action进行业务逻辑,比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者struts的action前统一设置字符集,或者去除掉一些非法字符(聊天室经常用到的,一些骂人的话)。filter 流程是线性的,url传来之后,检查之后,可保持原来的流程继续向下执行,被下一个filter, servlet接收。

    监听器(Listener):Java的监听器,也是系统级别的监听。监听器随web应用的启动而启动。Java的监听器在c/s模式里面经常用到,它会对特定的事件产生一个处理。监听在很多模式下用到,比如说观察者模式,就是一个使用监听器来实现的,在比如统计网站的在线人数。又比如struts2可以用监听来启动。Servlet监听器用于监听一些重要事件的发生,监听器对象可以在事情发生前、发生后可以做一些必要的处理。

    拦截器(Interceptor):java里的拦截器提供的是非系统级别的拦截,也就是说,就覆盖面来说,拦截器不如过滤器强大,但是更有针对性。Java中的拦截器是基于Java反射机制实现的,更准确的划分,应该是基于JDK实现的动态代理。它依赖于具体的接口,在运行期间动态生成字节码。拦截器是动态拦截Action调用的对象,它提供了一种机制可以使开发者在一个Action执行的前后执行一段代码,也可以在一个Action执行前阻止其执行,同时也提供了一种可以提取Action中可重用部分代码的方式。在AOP中,拦截器用于在某个方法或者字段被访问之前,进行拦截然后在之前或者之后加入某些操作。java的拦截器主要是用在插件上,扩展件上比如 Hibernate Spring Struts2等,有点类似面向切片的技术,在用之前先要在配置文件即xml,文件里声明一段的那个东西。

    三.SpringBoot使用过滤器

    两种方式:
    1.使用spring boot提供的FilterRegistrationBean注册Filter
    2.使用原生servlet注解定义Filter
    两种方式的本质都是一样的,都是去FilterRegistrationBean注册自定义Filter

    封装Filter

    package com.theeternity.common.baseFilter;
    
    import javax.servlet.Filter;
    
    /**
     * @program: ApiBoot
     * @description: 封装Filter
     * @author: TheEternity Zhang
     * @create: 2019-02-17 13:08
     */
    public interface MappingFilter extends Filter {
        String[] addUrlPatterns();
    
        int order();
    }
    

    自定义Filter

    package com.theeternity.beans.filterConfig;
    
    import com.theeternity.common.baseFilter.MappingFilter;
    import lombok.extern.slf4j.Slf4j;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import javax.servlet.*;
    import javax.servlet.FilterConfig;
    import java.io.IOException;
    
    /**
     * @program: ApiBoot
     * @description: 权限过滤器
     * @author: TheEternity Zhang
     * @create: 2019-02-17 13:14
     */
    public class AuthFilter implements MappingFilter {
    
        @Override
        public String[] addUrlPatterns() {
            return new String[]{"/*"};
        }
    
        @Override
        public int order() {
            return 0;
        }
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
    
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            filterChain.doFilter(servletRequest,servletResponse);
        }
    
        @Override
        public void destroy() {
    
        }
    
    }
    

    注册过滤器

    package com.theeternity.beans.filterConfig;
    
    import org.springframework.boot.web.servlet.FilterRegistrationBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    /**
     * @program: ApiBoot
     * @description: 注册过滤器
     * @author: TheEternity Zhang
     * @create: 2019-02-17 13:10
     */
    @Configuration
    public class FilterConfig {
    
        @Bean
        public FilterRegistrationBean registFilter() {
            FilterRegistrationBean registration = new FilterRegistrationBean();
            AuthFilter authFilter=new AuthFilter();
            registration.setFilter(authFilter);
            registration.addUrlPatterns(authFilter.addUrlPatterns());
            registration.setOrder(authFilter.order());
            registration.setName("AuthFilter");
            return registration;
        }
    }
    

    四.SpringBoot使用拦截器

    加粗样式封装Interceptor

    package com.theeternity.common.baseInterceptor;
    
    import org.springframework.web.servlet.HandlerInterceptor;
    
    /**
     * @program: ApiBoot
     * @description: 封装Interceptor
     * @author: TheEternity Zhang
     * @create: 2019-02-15 17:49
     */
    public interface MappingInterceptor extends HandlerInterceptor {
        String[] addPathPatterns();
    
        String[] excludePathPatterns();
    
        int order();
    }
    

    自定义Interceptor

    package com.theeternity.beans.interceptorConfig;
    
    import com.theeternity.common.baseInterceptor.MappingInterceptor;
    import org.springframework.stereotype.Component;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * @program: BoxApi
     * @description: 跨域拦截器
     * @author: tonyzhang
     * @create: 2018-12-21 14:44
     */
    @Component
    public class CrossOriginInterceptor implements MappingInterceptor {
    
        @Override
        public String[] addPathPatterns() {
            return new String[]{"/**"};
        }
    
        @Override
        public String[] excludePathPatterns() {
            return new String[0];
        }
    
        @Override
        public int order() {
            return 0;
        }
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            logger.info("允许的头信息"+request.getHeader("Origin"));
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "*");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
            //是否允许浏览器携带用户身份信息(cookie)
            response.setHeader("Access-Control-Allow-Credentials","true");
            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 {
    
        }
    }
    

    注册Interceptor

    package com.theeternity.beans.interceptorConfig;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    /**
     * @program: ApiBoot
     * @description: 拦截器注册
     * @author: TheEternity Zhang
     * @create: 2019-02-15 17:55
     */
    @Configuration
    public class InterceptorConfig implements WebMvcConfigurer {
    
        @Autowired
        private CrossOriginInterceptor crossOriginInterceptor;
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(crossOriginInterceptor).addPathPatterns(crossOriginInterceptor.addPathPatterns());
    
        }
    }
    
    展开全文
  • java拦截器和过滤器详解

    千次阅读 2022-01-06 17:14:14
    拦截器是基于java的反射机制的,而过滤器是基于函数回调。 拦截器不依赖与servlet容是依赖于spring容器,过滤器依赖与servlet容器。 拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用,可以...
  • 主要介绍了Java中的拦截器过滤器、监听器用法,详细分析了Java拦截器过滤器、监听器的功能、使用方法及相关注意事项,需要的朋友可以参考下
  • JAVA过滤器和拦截器的区别

    千次阅读 2020-03-22 16:01:43
    什么是拦截器 在AOP中用于在某个方法或字段被访问之前,进行拦截然后再之前货之后加入某些操作。拦截是AOP的一种实现策略。 拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者定义一个action前后...
  • 拦截器和过滤器的区别

    千次阅读 2021-03-04 00:21:24
    过滤器和拦截器的区别:①拦截器是基于java的反射机制的,而过滤器是基于函数回调。②拦截器不依赖与servlet容器,过滤器依赖与servlet容器。③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用...
  • 拦截器和过滤器的区别 过滤器和拦截器的区别: ①拦截器是基于java的反射机制的,而过滤器是基于函数回调。  ②拦截器不依赖与servlet容器,过滤器依赖与servlet容器。  ③拦截器只能对action请求起作用,而...
  • 总结:java过滤器和拦截器的区别?

    万次阅读 多人点赞 2018-12-13 18:33:44
    【扩展】 过滤器:Filter 概念:对目标资源的请求响应进行过滤截取。在请求到达servlet之前,进行逻辑判断,判断是否放行到servlet;也可以在一个响应response到达客户端之前进行过滤,判断是否允许返回客户端。 ...
  • 当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能。 过滤器细节 web.xml配置 <filter> <filter-name>demo1</filter-name> <filter-class>...
  • 本文通过代码分析文字说明的方式给大家浅析JAVA过滤器、监听器、拦截器的区别,感兴趣的朋友一起看下吧
  • 该压缩包实现了利用过滤器或者拦截器对登录信息进行验证跳转登陆页的功能,利用的是SpringBootthymeleaf,使用前请先看使用说明
  • java-web servlet 拦截器 过滤器使用 java-web servlet 拦截器 过滤器使用
  • 下面小编就为大家带来一篇java 过滤器filter防sql注入的实现代码。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 主要介绍了过滤器 拦截器的 6个区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 用到了接入权限和业务权限的鉴定,需要采用SpringMVC的拦截器,以前用Struts2的时候用过拦截器,而SpringMVC的拦截器功能之前没研究过,所以这次来稍微研究一下,得出的结论是SpringMVC的拦截器和Struts2的拦截器...
  • 过滤器拦截器简单流程及使用

    千次阅读 多人点赞 2020-07-22 09:01:42
    今天咱们来复习一下过滤器拦截器吧,这是每一个Java程序员都要求掌握的技术,不许说不会哦,不会就赶紧学习,嘿嘿,咱们抓紧时间,现在就开始吧 1. 过滤器拦截器的差异 过滤器和拦截器在功能上接近,但是他们有很大...
  • Java过滤器与SpringMVC拦截器之间的关系与区别

    万次阅读 多人点赞 2019-03-27 08:37:34
    1 拦截器是基于java的反射机制的,而过滤器是基于函数回调。 2 过滤器是servlet规范规定的,只能用于web程序中,而拦截器是在spring容器中,它不依赖servlet容器。 3 过滤器可以拦截几乎所有的请求(包含对静态资源...
  • Java中的拦截器和过滤器有什么区别

    千次阅读 2021-06-23 23:13:46
    3、过滤器基于函数回调方式实现,拦截器基于Java反射机制实现 (四)总结 实际开发中,拦截器的应用场景会比过滤器要更多,下面是拦截器和过滤器的主要应用场景 拦截器的应用场景:权限控制,日志打印,参数校验 ...
  • 本文主要总结拦截器和过滤器的不同,分5点进行比较,总结了适用场景以及在应用中的执行顺序
  • java 过滤器 + 拦截器 + JWT 原理以及实践
  • Java拦截器过滤器

    千次阅读 2022-04-22 23:42:23
    Java拦截器过滤器
  • 最近实现一个权限控制功能,想通过拦截器进行实现,当业务一切按预期一样完成,有一个特别控制需要再拦截器对参数进行解析使用,但是发现当我们再拦截器读取了输入流,再控制器是无法获取到参数的,这个是由于输入流...
  • java 干货,对接口参数进行中的特殊字符,如insert select * % 等进行判断,进行过滤.
  • 对项目中的所有参数去除前后空格...可以基于此过滤器实现过滤跨站脚本攻击,参数的增加,修改!敏感词汇过滤。实现原理为重写HttpServletRequestWrapper,获取参数的方法。include Forwarded 内部转发不在过滤之内。
  • 拦截器是基于java的反射机制的,而过滤器是基于函数回调。 ②拦截器不依赖与servlet容器,过滤器依赖与servlet容器。 ③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 91,911
精华内容 36,764
关键字:

java过滤器和拦截器

java 订阅