Spring Boot配置拦截器及实现跨域访问的方法

 更新时间:2018年12月18日 14:50:44   作者:湖人总冠军  
这篇文章主要介绍了Spring Boot配置拦截器及实现跨域访问的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

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

理论指导

问:Spring Boot怎么配置拦截器?

答:配置一个拦截器需要两步完成。

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

代码实现

目录结构:

具体代码:

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("-------------------------------------\n");
    sb.append("URI    : ").append(httpServletRequest.getRequestURI()).append("\n");
    sb.append("CostTime : ").append(executeTime).append("ms").append("\n");
    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的协议、域名、端口三者之间任意一与当前页面地址不同即为跨域。具体的看下表

URL
说明
是否允许通信
http://www.a.com/a.js
http://www.a.com/b.js
同一域名下
允许
http://www.a.com/lab/a.js
http://www.a.com/script/b.js
同一域名下不同文件夹
允许
http://www.a.com:8000/a.js
http://www.a.com/b.js
同一域名,不同端口
不允许
http://www.a.com/a.js
https://www.a.com/b.js
同一域名,不同协议
不允许
http://www.a.com/a.js
http://70.32.92.74/b.js
域名和域名对应ip
不允许
http://www.a.com/a.js
http://script.a.com/b.js
主域相同,子域不同
不允许
http://www.a.com/a.js
http://a.com/b.js
同一域名,不同二级域名(同上)
不允许(cookie这种情况下也不允许访问)
http://www.cnblogs.com/a.js
http://www.a.com/b.js
不同域名
不允许

上面代码是可以实现拦截器基本功能,但是这样是不可以跨域访问的,前端请求接口会有报错: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;
  }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • 详解Spring Boot Profiles 配置和使用

    详解Spring Boot Profiles 配置和使用

    本篇文章主要介绍了详解Spring Boot Profiles 配置和使用,具有一定的参考价值,有兴趣的可以了解一下
    2017-06-06
  • spring级联属性赋值的两种方式解析

    spring级联属性赋值的两种方式解析

    这篇文章主要介绍了spring级联属性赋值的两种方式解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01
  • 基于java Files类和Paths类的用法(详解)

    基于java Files类和Paths类的用法(详解)

    下面小编就为大家分享一篇基于java Files类和Paths类的用法详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2017-11-11
  • Java创建数组的几种方式总结

    Java创建数组的几种方式总结

    下面小编就为大家带来一篇Java创建数组的几种方式总结。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-10-10
  • MyBatis-Plus 乐观锁的具体实现

    MyBatis-Plus 乐观锁的具体实现

    MyBatis-Plus 的乐观锁通过简单的配置和注解,可以轻松实现高并发场景下的数据并发控制,具有一定的参考价值,感兴趣的可以了解一下
    2024-09-09
  • MyBatis 与 Spring 的完美整合方法

    MyBatis 与 Spring 的完美整合方法

    MyBatis 和 Spring 两大框架已经成了 Java 互联网技术主流框架组合,它们经受住了大数据量和大批量请求的考验,在互联网系统中得到了广泛的应用。这篇文章主要介绍了MyBatis 与 Spring 整合,需要的朋友可以参考下
    2018-04-04
  • 基于Java中进制的转换函数详解

    基于Java中进制的转换函数详解

    下面小编就为大家带来一篇基于Java中进制的转换函数详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • SpringBoot如何优雅的整合Swagger Api自动生成文档

    SpringBoot如何优雅的整合Swagger Api自动生成文档

    在多人协作的开发过程中,API文档不仅可以减少等待,也能保证开发的持续进行,这篇文章主要给大家介绍了关于SpringBoot如何优雅的整合Swagger Api自动生成文档的相关资料,需要的朋友可以参考下
    2021-07-07
  • JavaWeb 实现多个文件压缩下载功能

    JavaWeb 实现多个文件压缩下载功能

    文件下载时,我们可能需要一次下载多个文件,批量下载文件时,需要将多个文件打包为zip,然后再下载。本文给大家分享实现思路及具体实现代码,对javaweb实现文件压缩下载功能感兴趣的朋友一起学习吧
    2017-07-07
  • Spring Security如何为用户示例添加角色详解

    Spring Security如何为用户示例添加角色详解

    目前我正在用Java开发一个基于Spring Boot的web应用程序,下面这篇文章主要给大家介绍了关于Spring Security如何为用户示例添加角色的相关资料,需要的朋友可以参考下
    2022-10-10

最新评论