美文网首页
拦截器的配置以及解决跨域问题

拦截器的配置以及解决跨域问题

作者: 荒天帝886 | 来源:发表于2019-04-28 16:50 被阅读0次
    版本 时间 备注
    1.0 2019-04-28 创建笔记

    本章介绍拦截器和过滤器的区别,如何配置拦截器Interceptor以及在拦截器中解决跨域问题
    项目源码:https://gitee.com/fzyprojects/boot-test

    一、拦截器和过滤器的区别

    Spring的Interceptor和Servlet的Filter有相似之处,比如二者都是AOP编程思想的提现,都能实现权限检查,日志记录等。不同的是:

    • 使用范围不同。Filter是Servlet规范规定的,只能用于Web程序中。而拦截器既可以用于Web程序,也可以用于Application、Swing程序中。
    • 规范不同。Filter是Servlet规范规定的,拦截器是Spring定义的。
    • 使用资源不同。同其它代码块一样,拦截器也是一个Spring的组件,归Spring管理,配置在Spring文件中,因此可以使用Spring的所有资源、对象。例如Service对象、数据源和事务管理等,通过IOC注入到拦截器即可。而Filter无法做到这一点。
    • 深度不同。Filter只在Servlet前后起作用。而拦截器可以深入到方法前后,异常抛出前后等,因此拦截器具有更大的弹性。所以在Spring构建的程序中,要优先使用拦截器。

    二、拦截器的配置

    • 创建MyIntercepyor实现HandlerInterceptor
    • 重写preHandlepostHandleafterCompletion方法
    • 配置拦截器

    preHandle 请求处理之前需要执行的方法
    postHandle 请求处理之后执行的方法
    afterCompletion 请求生命周期结束之后执行的方法

    接口HandlerInterceptor
    public interface HandlerInterceptor {
        default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            return true;
        }
        default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
        }
        default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
        }
    }
    
    
    重写方法
    public class AreaInterceptor implements HandlerInterceptor {
        /**
         * 请求开始处理之前
         * @param request
         * @param response
         * @param handler
         * @return
         */
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
            System.out.println("*** preHandle-postHandle***");
            return true;
        }
        /**
         * 请求处理之后
         * @param request
         * @param response
         * @param handler
         * @param modelAndView
         */
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
            System.out.println("*** AreaInterceptor-postHandle***");
        }
    
        /**
         * 请求生命周期结束之后
         * @param request
         * @param response
         * @param handler
         * @param ex
         */
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
            System.out.println("*** AreaInterceptor-afterCompletion***");
        }
    }
    
    配置拦截器

    拦截器需要进行配置才能够使用。配置的目的是将拦截器交给springIOC容器管理。并且配置拦截器的使用条件

    • 配置拦截器实现WebMvcConfigurer,创建拦截器的Bean
      1. addInterceptor(拦截器)--> 将拦截器注册进来
      2. addPathPatterns("url")--> 添加需要拦截的请求
      3. excludePathPatterns("url")-->添加放行的请求,即不拦截
    @Configuration
    public class InterceptorConfiguration implements WebMvcConfigurer {
        private static final String ALL = "/**";
        private static final String LOGIN = "/inter/login";
        private static final String ERROR = "/error";
        private static final String TH = "/th/**";
        /**
         * 解决跨域问题
         * @return
         */
        @Bean
        public AreaInterceptor getAreaInterceptor() {
            return new AreaInterceptor();
        }
        /**
         * 返回单例对象
         * @return
         */
        @Bean
        public TokenInterceptor getMyInterceptor() {
            return new TokenInterceptor();
        }
        /**
         * 拦截器2
         * @return
         */
        @Bean
        public MyInterceptor2 getMyInterceptor2() {
            return new MyInterceptor2();
        }
        /**
         * addInterceptor(拦截器)--> 将拦截器注册进来
         * addPathPatterns("url")--> 添加需要拦截的请求
         * excludePathPatterns("url")-->添加放行的请求,即不拦截
         * <p>
         * 注意:如果要拦截所有请求,则拦截"/**"
         *
         * @param registry
         */
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(getAreaInterceptor()).addPathPatterns(ALL);
            registry.addInterceptor(getMyInterceptor()).addPathPatterns(ALL).excludePathPatterns(ERROR, LOGIN, TH);
            //registry.addInterceptor(getMyInterceptor2()).addPathPatterns("/**").excludePathPatterns("/inter/bbb","/inter/ccc");
        }
    }
    
    

    三、解决跨域问题

    请求发送端和接收端的ip地址以及端口号不一致都可能导致跨域问题,想要解决跨域问题,可以在拦截器中进行如下设置

    • 注意:需要禁止OPTIONS请求
    /**
     * 拦截器,解决跨域问题
     */
    public class AreaInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With");
            response.setHeader("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
            //浏览器会先发送一个试探请求OPTIONS,然后才会发送真正的请求,为了避免拦截器拦截两次请求,所以不能让OPTIONS请求通过
            if ("OPTIONS".equals(request.getRequestURI())){
                return false;
            }
            return true;
        }
    }
    

    终极解决方式1

    @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
            log.info("URI - [{}]",request.getRequestURI());
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Headers", "*");
            response.setHeader("Access-Control-Allow-Methods", "*");
            return true;
        }
    

    终极解决方式2

    @Configuration
    public class CorsConfig extends WebMvcConfigurerAdapter{
    
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedMethods("*")
                    .allowedOrigins("*");
        }
    }
    

    相关文章

      网友评论

          本文标题:拦截器的配置以及解决跨域问题

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