当前位置: 首页 > 编程笔记 >

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

楚流觞
2023-03-14
本文向大家介绍Spring Boot配置拦截器及实现跨域访问的方法,包括了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;
  }

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

 类似资料:
  • 本文向大家介绍SpringBoot拦截器实现登录拦截的方法示例,包括了SpringBoot拦截器实现登录拦截的方法示例的使用技巧和注意事项,需要的朋友参考一下 源码 GitHub:https://github.com/291685399/springboot-learning/tree/master/springboot-interceptor01 SpringBoot拦截器可以做什么 可以对UR

  • 本文向大家介绍golang实现跨域访问的方法,包括了golang实现跨域访问的方法的使用技巧和注意事项,需要的朋友参考一下 前端通过Ajax来获取服务器资源时,会存在跨域问题。因为Ajax只能同源使用(预防某些恶意行为),所以当访问不在同一个域中的资源时,就会出现跨域限制。尤其在开发和测试时,跨域问题会给前端测试带来非常不便。 不过CORS(Cross-Origin Resource Sharin

  • 本文向大家介绍js实现跨域访问的三种方法,包括了js实现跨域访问的三种方法的使用技巧和注意事项,需要的朋友参考一下 javascript跨域访问是web开发者经常遇到的问题,什么是跨域,一个域上加载的脚本获取或操作另一个域上的文档属性,下面将列出三种实现javascript跨域方法: 1.基于iframe实现跨域 基于iframe实现的跨域要求两个域具有aa.xx.com,bb.xx.com这种特

  • 本文向大家介绍Ajax实现跨域访问的三种方法,包括了Ajax实现跨域访问的三种方法的使用技巧和注意事项,需要的朋友参考一下 一、什么是跨域 我们先回顾一下域名地址的组成: http:// www . google : 8080 / script/jquery.js       http:// (协议号)                www  (子域名)              google (

  • 本文向大家介绍SpringBoot拦截器原理解析及使用方法,包括了SpringBoot拦截器原理解析及使用方法的使用技巧和注意事项,需要的朋友参考一下 拦截器简介 拦截器通常通过动态代理的方式来执行。 拦截器的生命周期由IoC容器管理,可以通过注入等方式来获取其他Bean的实例,使用更方便。 拦截器配置使用方式 实现拦截器接口: 将拦截器加入到配置中: 备注: 由于 preHandle、postH

  • 本文向大家介绍如何实现跨域访问?相关面试题,主要包含被问及如何实现跨域访问?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: JSONP:通过动态创建script,再请求一个带参网址实现跨域通信。document.domain + iframe跨域:两个页面都通过js强制设置document.domain为基础主域,就实现了同域。 JSONP:ajax请求受同源策略影响,不允许进行跨域请求,