前言
從Spring 6和Spring Boot 3開(kāi)始,Spring framework支持將遠(yuǎn)程HTTP服務(wù)代理為帶有HTTP交換注解方法的Java接口。類似的庫(kù),如OpenFeign和Retrofit,仍然可以使用,但HttpServiceProxyFactory添加了對(duì)Spring框架的原生支持。
聲明式HTTP接口
聲明式 http 客戶端主旨是使得編寫 java http 客戶端更容易。為了貫徹這個(gè)理念,采用了通過(guò)處理注解來(lái)自動(dòng)生成請(qǐng)求的方式(官方稱呼為聲明式、模板化)。通過(guò)聲明式 http 客戶端實(shí)現(xiàn)我們就可以在 java 中像調(diào)用一個(gè)本地方法一樣完成一次 http 請(qǐng)求,大大減少了編碼成本,同時(shí)提高了代碼可讀性。
舉個(gè)例子,如果想調(diào)用 /tenants 的接口,只需要定義如下的接口類即可
public interface TenantClient {
@GetExchange("/tenants")
Flux<User> getAll();
}
Spring 會(huì)在運(yùn)行時(shí)提供接口的調(diào)用的具體實(shí)現(xiàn),如上請(qǐng)求我們可以如 Java 方法一樣調(diào)用
@Autowired
TenantClient tenantClient;
tenantClient.getAll().subscribe(
);
如果我們想使用HTTP GET /users API,那么我們可以簡(jiǎn)單地編寫:
public interface UserClient {
@GetExchange("/users")
Flux<User> getAll();
}
Spring會(huì)在運(yùn)行時(shí)提供接口和exchange實(shí)現(xiàn),我們只需要調(diào)用getAll()方法。
@Autowired
UserClient userClient;
userClient.getAll().subscribe(
data -> log.info("User: {}", data)
);
測(cè)試使用
1. Maven
聲明式HTTP接口功能是spring-web依賴的一部分,當(dāng)我們引入spring-boot-starter-web或spring-boot-starter-webflux時(shí),它就會(huì)被傳遞引入。如果我們想添加響應(yīng)式支持,那么就包括后面的依賴。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- For reactive support -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
2.創(chuàng)建HTTP服務(wù)接口
在Spring中,HTTP服務(wù)接口是一個(gè)帶有@HttpExchange方法的Java接口。帶注釋的方法被視為HTTP端點(diǎn),細(xì)節(jié)通過(guò)注解屬性和輸入法參數(shù)類型靜態(tài)定義。
交流的方法
我們可以使用以下注解將方法標(biāo)記為HTTP服務(wù)端點(diǎn):
@HttpExchange:是指定HTTP端點(diǎn)的通用注釋。當(dāng)在接口級(jí)別使用時(shí),它適用于所有方法。
@GetExchange:為HTTP GET請(qǐng)求指定@HttpExchange。
@PostExchange:對(duì)于HTTP POST請(qǐng)求,指定@HttpExchange。
@PutExchange:為HTTP PUT請(qǐng)求指定@HttpExchange。
@DeleteExchange:對(duì)于HTTP DELETE請(qǐng)求,指定@HttpExchange。
@PatchExchange:對(duì)于HTTP Patch請(qǐng)求,指定@HttpExchange。
方法參數(shù)
exchange方法在方法簽名中支持下列方法參數(shù):
URI:設(shè)置請(qǐng)求的URL。
@PathVariable:將請(qǐng)求URL中的值替換為占位符。
@RequestBody:提供請(qǐng)求的主體。
@RequestParam:添加請(qǐng)求參數(shù)。當(dāng)“content-type”設(shè)置為“application/x-www-form-urlencoded”時(shí),請(qǐng)求參數(shù)會(huì)在請(qǐng)求體中編碼。否則,它們將作為URL查詢參數(shù)添加。
@ requesttheader:添加請(qǐng)求頭的名稱和值。
@RequestPart:可用于添加請(qǐng)求部分(表單字段,資源或HttpEntity等)。
@CookieValue:向請(qǐng)求中添加cookie。
示例代碼:
@PutExchange
void update(@PathVariable Long id, @RequestBody User user);
返回值
HTTP exchange方法可以返回如下值:
阻塞或反應(yīng)性(Mono/Flux)。
只有特定的響應(yīng)信息,如狀態(tài)碼和/或響應(yīng)頭。
Void,表示該方法僅被視為execute方法;
對(duì)于阻塞交換方法,我們通常應(yīng)該返回ResponseEntity,而對(duì)于響應(yīng)式方法,我們可以返回Mono/Flux類型。
//阻塞性
@GetExchange("/{id}")
User getById(...);
//Reactive
@GetExchange("/{id}")
Mono<User> getById(...);
3.構(gòu)建HttpServiceProxyFactory
HttpServiceProxyFactory是一個(gè)從HTTP服務(wù)接口創(chuàng)建客戶端代理的工廠。使用它的HttpServiceProxyFactory.builder(client).build()方法來(lái)獲取代理bean的實(shí)例。
import com.fasterxml.jackson.databind.ObjectMapper;
import com.leftso.app.web.UserClient;
import lombok.SneakyThrows;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.support.WebClientAdapter;
import org.springframework.web.service.invoker.HttpServiceProxyFactory;
@Configuration
public class WebConfig {
@Bean
WebClient webClient(ObjectMapper objectMapper) {
return WebClient.builder()
.baseUrl("https://jsonplaceholder.typicode.com/")
.build();
}
@SneakyThrows
@Bean
UserClient postClient(WebClient webClient) {
HttpServiceProxyFactory httpServiceProxyFactory =
HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient))
.build();
return httpServiceProxyFactory.createClient(UserClient.class);
}
}
注意,我們已經(jīng)在WebClient bean中設(shè)置了遠(yuǎn)程API的基礎(chǔ)URL,因此我們只需要在交換方法中使用相對(duì)路徑。
4. HTTP業(yè)務(wù)接口示例
下面是與https://jsonplaceholder.typicode.com/users/端點(diǎn)交互并執(zhí)行各種操作的HTTP接口示例。
import com.leftso.app.model.User;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.service.annotation.DeleteExchange;
import org.springframework.web.service.annotation.GetExchange;
import org.springframework.web.service.annotation.HttpExchange;
import org.springframework.web.service.annotation.PostExchange;
import org.springframework.web.service.annotation.PutExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@HttpExchange(url = "/users", accept = "application/json", contentType = "application/json")
public interface UserClient {
@GetExchange("/")
Flux<User> getAll();
@GetExchange("/{id}")
Mono<User> getById(@PathVariable("id") Long id);
@PostExchange("/")
Mono<ResponseEntity<Void>> save(@RequestBody User user);
@PutExchange("/{id}")
Mono<ResponseEntity<Void>> update(@PathVariable Long id, @RequestBody User user);
@DeleteExchange("/{id}")
Mono<ResponseEntity<Void>> delete(@PathVariable Long id);
}
注意,我們創(chuàng)建了一個(gè)User類型的記錄來(lái)保存用戶信息。
public record User(Long id, String name, String username, String email) {}
現(xiàn)在我們可以將UserClient bean注入到應(yīng)用程序類中,并調(diào)用方法以獲取API響應(yīng)。
@Autowired
UserClient userClient;
//獲取所有用戶
userClient.getAll().subscribe(
data -> log.info("User: {}", data)
);
//通過(guò)id獲取用戶
userClient.getById(1L).subscribe(
data -> log.info("User: {}", data)
);
//創(chuàng)建一個(gè)新用戶
userClient.save(new User(null, "Lokesh", "lokesh", "admin@email.com"))
.subscribe(
data -> log.info("User: {}", data)
);
//通過(guò)id刪除用戶
userClient.delete(1L).subscribe(
data -> log.info("User: {}", data)
);
總結(jié)
在這個(gè)Spring(Spring Boot 3.0)教程中,我們通過(guò)示例學(xué)習(xí)了如何創(chuàng)建和使用聲明式HTTP客戶端接口。
Spring Boot3.0王炸版本帶來(lái)了很多新特性,值得我們深入學(xué)習(xí)
推薦給大家嗶站上動(dòng)力節(jié)點(diǎn)王媽媽的springboot3教程,采用知識(shí)點(diǎn)配合項(xiàng)目案例的方式,可以讓大家很輕松的掌握SpringBoot
配套資料也非常全面,領(lǐng)取方式可看視頻簡(jiǎn)介區(qū)~
點(diǎn)擊這里開(kāi)始 快速學(xué)習(xí)文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-594465.html
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-594465.html
到了這里,關(guān)于【微服務(wù)|SpringBoot 3.0】 新特性——內(nèi)置聲明式HTTP客戶端的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!