美文网首页SpringBoot专题
springboot使用过滤器、拦截器

springboot使用过滤器、拦截器

作者: Mracale | 来源:发表于2021-06-21 15:42 被阅读0次

    1.过滤器
    使用Filter的实现类完成对/filter/*这样的url的来访的数据的过滤。

    1.1和之前创建项目一样,只需要一个web组件即可。


    image.png

    1.2编写controller


    image.png

    可修改为如下:
    1.@RequestMapping(value = “”,method = RequestMethod.GET)表示通过get的方法获取值,get是默认方法,可以省略。
    2.在方法上可以直接使用@GetMapping(value = “”)直接可以表示用get方法获取值。


    image.png

    1.3 过滤器

    package com.qianliu.springboot_test.filter;
    import java.io.IOException;
    
    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 org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.core.annotation.Order;
    import org.springframework.stereotype.Component;
    
    //将servlet过滤器配置起来
    //1.urlPatterns = "/*"表示过滤的url的正则表达式
    @Order(1) //多个filter的时候此过滤器的顺序第一
    @WebFilter(urlPatterns = "/filter/*", filterName = "SimpleFilter")
    public class SimpleFilter implements Filter {
        //获取日志
        private Logger logger = LoggerFactory.getLogger(this.getClass());
    
        @Override
        public void destroy() {}
    
        //打印过来的请求的host和address
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterchain)
                throws IOException, ServletException {
    
            logger.info("Remote Host:"+request.getRemoteHost());
            logger.info("Remote Address:"+request.getRemoteAddr());
            filterchain.doFilter(request, response);
            /*
            //过滤没有登陆的人
            if(request.getParameter("user")!=null){
                filterchain.doFilter(request, response);
            }
            */
        }
    
        @Override
        public void init(FilterConfig filterconfig) throws ServletException {}
    }
    

    1.4配置好servlet扫描器


    image.png

    1.5测试


    image.png

    结果正确(图片中的interceptor和configuration都是拦截器中的代码,这张图的拦截器代码并没有完成时的截图):

    2.拦截器
    利用拦截器来实现对进入"/interceptor/*"这个url下的拦截,如果进入的时候session里面有“name”,那么就放行,并打印出“name”。

    2.1 定义拦截器

    package com.qianliu.springboot_test.interceptor;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    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;
    
    @Component //@Component标签相当于配置文件中的<bean id="" class=""/>,以后可以直接放入到@Configuration标注的类中
    public class SimpleIntercepter implements HandlerInterceptor {
        //获取日志
        private Logger logger = LoggerFactory.getLogger(this.getClass());
    
        /*
         * 进入controller层之前拦截请求
         */
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            //不是含有"/interceptor"的链接不进行拦截
            if(!request.getRequestURI().contains("/interceptor")){
                return true;
            }
    
            //查看session里面是否有"name"的数据
            String name = null;
            if((name = (String) request.getSession().getAttribute("name"))!=null){
                logger.info("user:"+name+"进入网站。。");
                return true;
            }
    
            return false;
        }
    
        /*
         * 处理请求完成后视图渲染之前的处理操作
         */
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            logger.info("postHandle..................");
        }
    
        /*
         * 视图渲染之后的操作
         */
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            logger.info("afterCompletion...............");
        }
    }
    

    2.2 springboot2.x注册拦截器的方式

    package com.qianliu.springboot_test.utils.configuration;
    
    import com.qianliu.springboot_test.interceptor.SimpleIntercepter;
    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;
    
    /*
     * @author qianliu on 2019/5/16 21:43
     * @Discription:注册SimpleIntercepter拦截器并注册拦截的url
     */
    @Configuration //SimpleIntercepter相当于一个Bean,因为它被@Component标注过
    public class UserInterceptorAppConfig implements WebMvcConfigurer {
        @Resource
        SimpleIntercepter simpleIntercepter;
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(simpleIntercepter).addPathPatterns("/interceptor/*");
        }
    }
    

    2.3编写controller


    image.png

    2.4测试
    先在浏览器:http://localhost:8080/filter/xiaoming
    再输入:http://localhost:8080/interceptor/xiaoming

    image.png

    正常进入程序:


    image.png

    拦截器和过滤器的区别:

    1.对于自定义 Controller 的请求分发流程:
    
    Filter 过滤请求处理;
    Interceptor 拦截请求处理;
    对应的 HandlerAdapter 处理请求;
    Interceptor 拦截响应处理;
    Interceptor 的最终处理;
    Filter 过滤响应处理。
    
    2.机制不同:
    
    Filter 是基于 函数回调的,而 Interceptor 则是基于 Java反射 和 动态代理。
    Filter 依赖于 Servlet 容器,而 Interceptor 不依赖于 Servlet 容器。
    Filter 对几乎 所有的请求 起作用,而 Interceptor 只对 Controller 对请求起作用。
    
    

    @Autowired与@Resource用法相似,下面是两者的区别:
    (1).@Autowired 与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上;
    (2).@Autowired 默认按类型装配,默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设
    置它的required属性为false,如:@Autowired(required=false) .如果我们想使用名称装配可以结合 @Qualifier注解进行使用;

    3.@Resource(这个注解属于J2EE的),默认安装名称进行装配,名称可以通过name属性进行指定,如果没
    有指定name属性,当注解写在字段上时,默认取字段名进行安装名称查找,如果注解写在setter方法上默认取属
    性名进行装配。当找不到与名称匹配的bean时才按照类型进行装 配。但是需要注意的是,如果name属性一旦指
    定,就只会按照名称进行装配。

    推荐使用@Resource注解在字段上,这样就不用写setter方法了.并且这个注解是属于J2EE的,减少了与Spring
    的耦合,这样代码看起就比较优雅 。

    相关文章

      网友评论

        本文标题:springboot使用过滤器、拦截器

        本文链接:https://www.haomeiwen.com/subject/pimyyltx.html