SpringBoot整合Web之CORS支持與配置類和 XML配置及注冊(cè)攔截器
本章概要
- CORS 支持
- 配置類與 XML 配置
- 注冊(cè)攔截器
CORS 支持
CORS (Cross-Origin Resource Sharing)是由 W3C 制定開發(fā)的一種跨域資源共享技術(shù)標(biāo)準(zhǔn),其目的就是為了解決前端的跨域請(qǐng)求。在 Java EE 開發(fā)中,最常見的前端跨域請(qǐng)求解決方案是 JSONP ,但是 JSONP 只支持 GET 請(qǐng)求,而 CORS 則支持多種 HTTP 請(qǐng)求方法。
GET、POST、HEAD 請(qǐng)求流程:響應(yīng)頭中有一個(gè) Access-Control-Orgin 字段,用來記錄可以訪問該資源的域。當(dāng)瀏覽器收到這樣的響應(yīng)頭信息后,提取 Access-Control-Orgin 字段中的值,發(fā)現(xiàn)該值包含當(dāng)前頁面所在的域,就知道這個(gè)跨域是被允許的。
DELETE、PUT 及 自定義請(qǐng)求等請(qǐng)求流程:以 DELETE 請(qǐng)求為例,當(dāng)前端發(fā)起一個(gè) DELETE 請(qǐng)求時(shí),這個(gè)請(qǐng)求的處理會(huì)經(jīng)過兩個(gè)步驟。第一步,發(fā)送一個(gè) OPTIONS 請(qǐng)求詢問服務(wù)端是否具備該資源的 DELETE 權(quán)限,服務(wù)端給瀏覽器響應(yīng), Allow 頭信息表示服務(wù)端支持的請(qǐng)求方法。第二步,發(fā)送 DELETE 請(qǐng)求,服務(wù)端再次給出一次響應(yīng)。
無論是簡(jiǎn)單請(qǐng)求還是自定義請(qǐng)求,前端的寫法都不變,額外的處理都是在服務(wù)端來完成的。在傳統(tǒng) Java EE 開發(fā)中,可以通過過濾器統(tǒng)一配置,而 Spring Boot 中對(duì)此則提供了更簡(jiǎn)潔的解決方案。
1. 創(chuàng)建SpringBoot工程
創(chuàng)建 Spring Boot 工程,添加 Web 依賴,如下
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
2. 創(chuàng)建控制器
@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. 配置跨域
跨域有兩個(gè)地方可以配置,一個(gè)是直接在相應(yīng)的請(qǐng)求方法上加注解:
@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 域的請(qǐng)求是支持跨域的
- maxAge 表示探測(cè)請(qǐng)求的有效期,探測(cè)請(qǐng)求不用每次都發(fā)送,可以配置一個(gè)有效期,有效期過了之后才會(huì)發(fā)送探測(cè)請(qǐng)求,默認(rèn)1800秒
- allowedHeaders 表示允許的請(qǐng)求頭,“*” 表示所有的請(qǐng)求頭都被允許
這種配置方式是一種細(xì)粒度的配置,可以控制到每一個(gè)方法上。也可以不再每個(gè)方法上加 @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("進(jìn)入跨域配置"); } }
代碼解釋:
- 全局配置需要自定義實(shí)現(xiàn) WebMvcConfigurer 接口,然后實(shí)現(xiàn)接口中的 addCorsMappings 方法
- 在 addCorsMappings 方法中,addMapping 表示對(duì)哪種格式的請(qǐng)求路徑進(jìn)行跨域處理;allowedHeaders 表示允許的請(qǐng)求頭,默認(rèn)允許所有的請(qǐng)求頭信息;allowedMethods表示允許的請(qǐng)求方法,默認(rèn)是 GET 、POST 和 HEAD , * 表示支持所有的請(qǐng)求方法; maxAge表示探測(cè)請(qǐng)求的有效期;allowedOrigins表示支持的域
上面兩種配置方式,選擇一種即可,然后啟動(dòng)項(xiàng)目。
4. 測(cè)試
新建一個(gè)Spring Boot 項(xiàng)目,添加Web依賴,然后在 resources/static 目錄下加入jquery.js并創(chuàng)建一個(gè)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="提交數(shù)據(jù)" onclick="getData()"><br> <input type="button" value="刪除數(shù)據(jù)" 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>
運(yùn)行項(xiàng)目,訪問"http://localhost:8081/index.html",查看結(jié)果
配置類與 XML 配置
Spring Boot 推薦使用 Java 完成相關(guān)的配置工作。在項(xiàng)目中,不建議將所有的配置放在一個(gè)配置類中,可以根據(jù)不同的需求提供不同的配置類,例如專門處理Spring Security 的配置類、提供 Bean 的配置類、Spring MVC 相關(guān)的配置類。這些配置上都需要添加 @Configuration,@ComponentScan 注解會(huì)掃描所有的 Spring 組件,也包括 @Configuration 。@ComponentScan注解 在項(xiàng)目入口類的 @SpringBootApplication 注解中已經(jīng)提供,因此在實(shí)際項(xiàng)目中只需要按需提供相關(guān)配置類即可。
Spring Boot 中并不推薦使用 XML配置。如果需要使用 XML 配置,只需要在 resources 目錄下提供配置文件 然后通過 @ImportResource 加載配置文件即可,例如,有一個(gè) 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>
然后創(chuàng)建 Bean 配置類,導(dǎo)入 XML 配置
@Configuration @ImportResource("classpath:beans.xml") public class Beans { }
最后在 Controller 中就可以直接導(dǎo)入 Hello 類使用了:
@RestController public class HelloController { @Autowired Hello hello; @GetMapping("/hello") public String hello(){ return hello.sayHello("嗨嘍!"); } }
注冊(cè)攔截器
Spring Boot 中提供了 AOP 風(fēng)格的攔截器,擁有更加精細(xì)的攔截處理能力。Spring Boot 中攔截器的注冊(cè)更加方便。
步驟1:創(chuàng)建一個(gè) Spring Boot 項(xiàng)目,添加 spring-boot-starter-web 依賴。
步驟2:創(chuàng)建攔截器實(shí)現(xiàn) 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 的順序執(zhí)行。注意,只有 preHandle 方法返回 true 時(shí)后面的方法才會(huì)執(zhí)行。當(dāng)攔截器鏈內(nèi)存在多個(gè)攔截?cái)r截器時(shí),postHandle 在攔截器鏈內(nèi)的所有的攔截器返回成功時(shí)才會(huì)調(diào)用,而 afterCompletion 只有 preHandle 返回 true 才會(huì)調(diào)用,若攔截器鏈內(nèi)的第一個(gè)攔截器的 preHandle 方法返回 false ,則后面的方法都不會(huì)執(zhí)行。
步驟3:配置攔截器。定義配置類進(jìn)行攔截器的配置,如下
@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new MyInterceptor1()) .addPathPatterns("/**") .excludePathPatterns("/hello"); } }
自定義實(shí)現(xiàn) WebMvcConfigurer 接口,實(shí)現(xiàn)接口中的 addInterceptors 方法。其中,addPathPatterns表示攔截路徑,excludePathPatterns 表示排除的路徑。
步驟4:測(cè)試。在瀏覽器中訪問 /hello 和 /hello2 接口,當(dāng)訪問 /hello2 時(shí),打印日志如下:
MyInterceptor1>>>preHandle
MyInterceptor1>>>postHandle
MyInterceptor1>>>afterCompletion
到此這篇關(guān)于SpringBoot整合Web之CORS支持與配置類和 XML配置及注冊(cè)攔截器的文章就介紹到這了,更多相關(guān)SpringBoot CORS支持內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- springboot項(xiàng)目數(shù)據(jù)庫(kù)配置類DatabaseConfig示例詳解
- SpringBoot控制配置類加載順序方式
- SpringBoot通過自定義注解實(shí)現(xiàn)配置類的自動(dòng)注入的實(shí)現(xiàn)
- Springboot自動(dòng)配置與@Configuration配置類詳解
- SpringBoot中的配置類(@Configuration)
- SpringBoot2底層注解@Configuration配置類詳解
- springboot 跨域配置類及跨域請(qǐng)求配置
- springboot如何實(shí)現(xiàn)導(dǎo)入其他配置類
相關(guān)文章
MyBatis使用<foreach>標(biāo)簽like查詢報(bào)錯(cuò)解決問題
這篇文章主要介紹了MyBatis使用<foreach>標(biāo)簽like查詢報(bào)錯(cuò)解決問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03java集合Collection實(shí)現(xiàn)類解析ArrayList?LinkedList及Vector
這篇文章主要為大家介紹了java集合Collection實(shí)現(xiàn)類解析ArrayList?LinkedList及Vector,有需要的朋友可以借鑒參考下,希望能夠有所幫助2022-03-03springboot實(shí)現(xiàn)執(zhí)行sql語句打印到控制臺(tái)
這篇文章主要介紹了springboot實(shí)現(xiàn)執(zhí)行sql語句打印到控制臺(tái)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06Java中字符串轉(zhuǎn)int數(shù)據(jù)類型的三種方式
這篇文章主要介紹了Java中字符串轉(zhuǎn)int數(shù)據(jù)類型的三種方式,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03