SpringBoot整合Web之CORS支持与配置类和 XML配置及注册拦截器
作者:一只小熊猫呀
本章概要
- CORS 支持
- 配置类与 XML 配置
- 注册拦截器
CORS 支持
CORS (Cross-Origin Resource Sharing)是由 W3C 制定开发的一种跨域资源共享技术标准,其目的就是为了解决前端的跨域请求。在 Java EE 开发中,最常见的前端跨域请求解决方案是 JSONP ,但是 JSONP 只支持 GET 请求,而 CORS 则支持多种 HTTP 请求方法。
GET、POST、HEAD 请求流程:响应头中有一个 Access-Control-Orgin 字段,用来记录可以访问该资源的域。当浏览器收到这样的响应头信息后,提取 Access-Control-Orgin 字段中的值,发现该值包含当前页面所在的域,就知道这个跨域是被允许的。
DELETE、PUT 及 自定义请求等请求流程:以 DELETE 请求为例,当前端发起一个 DELETE 请求时,这个请求的处理会经过两个步骤。第一步,发送一个 OPTIONS 请求询问服务端是否具备该资源的 DELETE 权限,服务端给浏览器响应, Allow 头信息表示服务端支持的请求方法。第二步,发送 DELETE 请求,服务端再次给出一次响应。
无论是简单请求还是自定义请求,前端的写法都不变,额外的处理都是在服务端来完成的。在传统 Java EE 开发中,可以通过过滤器统一配置,而 Spring Boot 中对此则提供了更简洁的解决方案。
1. 创建SpringBoot工程
创建 Spring Boot 工程,添加 Web 依赖,如下
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
2. 创建控制器
@RestController @RequestMapping("/book") public class BookController { @PostMapping("/") public String addBook(String name){ return "receive:"+name; } @DeleteMapping("/{id}") public String deleteBookById(@PathVariable long id){ return String.valueOf(id); } }
3. 配置跨域
跨域有两个地方可以配置,一个是直接在相应的请求方法上加注解:
@RestController @RequestMapping("/book") public class BookController { @PostMapping("/") @CrossOrigin(value = "http://localhost:8081",maxAge = 1800,allowedHeaders = "*") public String addBook(String name){ return "receive:"+name; } @DeleteMapping("/{id}") @CrossOrigin(value = "http://localhost:8081",maxAge = 1800,allowedHeaders = "*") public String deleteBookById(@PathVariable long id){ return String.valueOf(id); } }
代码解释:
- @CrossOrigin 中的 value 表示支持的域,这里表示来自 http://localhost:8081 域的请求是支持跨域的
- maxAge 表示探测请求的有效期,探测请求不用每次都发送,可以配置一个有效期,有效期过了之后才会发送探测请求,默认1800秒
- allowedHeaders 表示允许的请求头,“*” 表示所有的请求头都被允许
这种配置方式是一种细粒度的配置,可以控制到每一个方法上。也可以不再每个方法上加 @CrossOrigin 注解,而是采用全局配置,如下:
@Configuration public class MyWebMvcConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/book/**") .allowedHeaders("*") .allowedMethods("*") .maxAge(1800) .allowedOrigins("http://localhost:8081"); System.out.println("进入跨域配置"); } }
代码解释:
- 全局配置需要自定义实现 WebMvcConfigurer 接口,然后实现接口中的 addCorsMappings 方法
- 在 addCorsMappings 方法中,addMapping 表示对哪种格式的请求路径进行跨域处理;allowedHeaders 表示允许的请求头,默认允许所有的请求头信息;allowedMethods表示允许的请求方法,默认是 GET 、POST 和 HEAD , * 表示支持所有的请求方法; maxAge表示探测请求的有效期;allowedOrigins表示支持的域
上面两种配置方式,选择一种即可,然后启动项目。
4. 测试
新建一个Spring Boot 项目,添加Web依赖,然后在 resources/static 目录下加入jquery.js并创建一个index.html文件,如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="jquery3.3.1.js"></script> </head> <body> <div id="contentDiv"></div> <div id="deleteResult"></div> <input type="button" value="提交数据" onclick="getData()"><br> <input type="button" value="删除数据" onclick="deleteData()"><br> <script> function getData() { $.ajax({ url: 'http://localhost:8081/book/', type: 'get', success: function (msg) { $("#contentDiv").html(msg); } }) } function deleteData() { $.ajax({ url: 'http://localhost:8081/book/99', type: 'delete', success: function (msg) { $("#deleteResult").html(msg); } }) } </script> </body> </html>
运行项目,访问"http://localhost:8081/index.html",查看结果
配置类与 XML 配置
Spring Boot 推荐使用 Java 完成相关的配置工作。在项目中,不建议将所有的配置放在一个配置类中,可以根据不同的需求提供不同的配置类,例如专门处理Spring Security 的配置类、提供 Bean 的配置类、Spring MVC 相关的配置类。这些配置上都需要添加 @Configuration,@ComponentScan 注解会扫描所有的 Spring 组件,也包括 @Configuration 。@ComponentScan注解 在项目入口类的 @SpringBootApplication 注解中已经提供,因此在实际项目中只需要按需提供相关配置类即可。
Spring Boot 中并不推荐使用 XML配置。如果需要使用 XML 配置,只需要在 resources 目录下提供配置文件 然后通过 @ImportResource 加载配置文件即可,例如,有一个 Hello 类,如下:
public class Hello { public String sayHello(String name){ return "hello" + name; } }
在resources 目录下新建 beans.xml 文件配置该类:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean class="com.sang.chapter04.Hello" id="hello"/> </beans>
然后创建 Bean 配置类,导入 XML 配置
@Configuration @ImportResource("classpath:beans.xml") public class Beans { }
最后在 Controller 中就可以直接导入 Hello 类使用了:
@RestController public class HelloController { @Autowired Hello hello; @GetMapping("/hello") public String hello(){ return hello.sayHello("嗨喽!"); } }
注册拦截器
Spring Boot 中提供了 AOP 风格的拦截器,拥有更加精细的拦截处理能力。Spring Boot 中拦截器的注册更加方便。
步骤1:创建一个 Spring Boot 项目,添加 spring-boot-starter-web 依赖。
步骤2:创建拦截器实现 HandlerInterceptor 接口
public class MyInterceptor1 implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { System.out.println("MyInterceptor1>>>preHandle"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) { System.out.println("MyInterceptor1>>>postHandle"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { System.out.println("MyInterceptor1>>>afterCompletion"); } }
拦截器中的方法将按 preHandle --> Controller --> postHandle --> afterCompletion 的顺序执行。注意,只有 preHandle 方法返回 true 时后面的方法才会执行。当拦截器链内存在多个拦截拦截器时,postHandle 在拦截器链内的所有的拦截器返回成功时才会调用,而 afterCompletion 只有 preHandle 返回 true 才会调用,若拦截器链内的第一个拦截器的 preHandle 方法返回 false ,则后面的方法都不会执行。
步骤3:配置拦截器。定义配置类进行拦截器的配置,如下
@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new MyInterceptor1()) .addPathPatterns("/**") .excludePathPatterns("/hello"); } }
自定义实现 WebMvcConfigurer 接口,实现接口中的 addInterceptors 方法。其中,addPathPatterns表示拦截路径,excludePathPatterns 表示排除的路径。
步骤4:测试。在浏览器中访问 /hello 和 /hello2 接口,当访问 /hello2 时,打印日志如下:
MyInterceptor1>>>preHandle
MyInterceptor1>>>postHandle
MyInterceptor1>>>afterCompletion
到此这篇关于SpringBoot整合Web之CORS支持与配置类和 XML配置及注册拦截器的文章就介绍到这了,更多相关SpringBoot CORS支持内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!