zoukankan      html  css  js  c++  java
  • Spring Boot配置拦截器及实现跨域访问

    拦截器功能强大,能够深入方法前后,常应用于日志记录、权限检查和性能检测等,几乎是项目中不可或缺的一部分,本文就来实现Spring Boot自定义拦截器的配置。

    理论指导

    :Spring Boot怎么配置拦截器?
    :配置一个拦截器需要两步完成。
    1. 自定义拦截器,实现HandlerInterceptor这个接口。这个接口包括三个方法,preHandle是请求执行前执行的,postHandler是请求结束执行的,但只有preHandle方法返回true的时候才会执行,afterCompletion是视图渲染完成后才执行,同样需要preHandle返回true,该方法通常用于清理资源等工作。
    1. 注册拦截器。 作用是确定拦截器和拦截的URL。需要继承WebMvcConfigurationSupport并重写addInterceptor方法,WebMvcConfigureAdapter已经过时了!!

    代码实现

    目录结构:

    TimeCostInterceptor是一个功能齐全的拦截器,需要用到util里面的工具类,由于代码较多,感兴趣的可以到GitHub中查看源码。

    具体代码:

    MyInterceptor.java

    public class MyInterceptor implements HandlerInterceptor {
    
        /**
         * preHandle在执行Controller之前执行,返回true,则继续执行Contorller
         * 返回false则请求中断。
         */
        @Override
        public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o)
                throws Exception {
            //只有返回true才会继续向下执行,返回false取消当前请求 
            long startTime = System.currentTimeMillis();
            httpServletRequest.setAttribute("startTime", startTime);
            return true;
        }
    
        /**
         * postHandle是在请求执行完,但渲染ModelAndView返回之前执行
         */
        @Override
        public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o,
                ModelAndView modelAndView) throws Exception {
            long startTime = (Long) httpServletRequest.getAttribute("startTime");
            long endTime = System.currentTimeMillis();
            long executeTime = endTime - startTime;
            StringBuilder sb = new StringBuilder(1000);
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String date = simpleDateFormat.format(new Date());
            sb.append("-----------------------").append(date).append("-------------------------------------
    ");
            sb.append("URI       : ").append(httpServletRequest.getRequestURI()).append("
    ");
            sb.append("CostTime  : ").append(executeTime).append("ms").append("
    ");
            sb.append("-------------------------------------------------------------------------------");
            System.out.println(sb.toString());
        }
    
        /**
         * afterCompletion是在整个请求执行完毕后执行
         */
        @Override
        public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
                Object o, Exception e) throws Exception {
        }
    
    }

    RegisterInterceptor.java

    /**
     * 继承WebMvcConfigurationSupport继承并重写addInterceptor方法用于注册拦截器
     * WebMvcConfigureAdapter已经过时了!!
     */
    @Configuration
    public class RegisterInterceptor extends WebMvcConfigurationSupport {
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
            super.addInterceptors(registry);
        }
    }

    拦截效果


    更新

    跨域访问

    由于JavaScript同源策略,凡是发送请求url的协议、域名、端口三者之间任意一与当前页面地址不同即为跨域。具体的看下表(来源于javascript跨域资源总结与解决办法):

    URL
    说明
    是否允许通信
    同一域名下
    允许
    同一域名下不同文件夹
    允许
    同一域名,不同端口
    不允许
    同一域名,不同协议
    不允许
    域名和域名对应ip
    不允许
    主域相同,子域不同
    不允许
    同一域名,不同二级域名(同上)
    不允许(cookie这种情况下也不允许访问)
    不同域名
    不允许

    上面代码是可以实现拦截器基本功能,但是这样是不可以跨域访问的,前端请求接口会有报错:XMLHttpRequest cannot loadhttp://xxx/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

    解决方案是设置请求头Access-Control-Allow-Origin为“*”或者设置为和request相同的Origin。

    ①在拦截器中添加一个设置请求头的方法。

        public void crossDomain(HttpServletRequest request, HttpServletResponse response) {
            response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
            response.setHeader("Access-Control-Allow-Credentials", "true");
        }

    ②在preHandle中调用这个方法。

      public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception {
            crossDomain(request, response);
            long startTime = System.currentTimeMillis();
            request.setAttribute("startTime", startTime);
            return true;
        }

    完整代码:GItHub地址

  • 相关阅读:
    IOC(inverse of Control)控制反转(依赖注入)思想
    学习Ajax技术总结
    设计差异引发WebServices 安全性问题
    XML与Webservices相关的安全问题概述
    XML与Webservices相关的安全问题概述
    设计差异引发WebServices 安全性问题
    Webservice测试方案(目录及下载链接)
    XML与Webservices相关的安全问题概述
    设计差异引发WebServices 安全性问题
    构建安全的 Web Services
  • 原文地址:https://www.cnblogs.com/sgh1023/p/10056859.html
Copyright © 2011-2022 走看看