最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring元注解@HttpExchange聲明式調(diào)用HTTP

 更新時(shí)間:2025年10月05日 10:35:39   作者:小猿、  
這篇文章主要介紹了Spring元注解@HttpExchange聲明式調(diào)用HTTP,Spring?Framework6和Spring?Boot3引入了聲明式HTTP客戶端@HttpExchange,通過接口注解簡(jiǎn)化REST?API調(diào)用,核心注解包括@GetExchange、@PostExchange等對(duì)應(yīng)HTTP方法,支持路徑參數(shù)和請(qǐng)求體,需要的朋友可以參考下

1. 概述

在 Spring 框架中,進(jìn)行 HTTP 調(diào)用是常見的需求。過去,我們可能會(huì)使用 RestTemplate。隨后,更現(xiàn)代、非阻塞的 WebClient 成為了推薦選擇。然而,直接使用 WebClient 仍然需要編寫較多的模板代碼。

為了進(jìn)一步簡(jiǎn)化開發(fā),Spring Framework 6 和 Spring Boot 3 引入了 聲明式 HTTP 客戶端 的支持,其核心注解就是 @HttpExchange。這個(gè)注解可以看作是 Spring Cloud OpenFeign 在 Spring 原生生態(tài)中的現(xiàn)代化替代品,它允許開發(fā)者通過定義一個(gè) Java 接口來優(yōu)雅地描述遠(yuǎn)程 HTTP API,而無需實(shí)現(xiàn)具體的調(diào)用邏輯。

@HttpExchange 是一個(gè)元注解,它派生出了一系列更具體的注解,如 @GetExchange@PostExchange@PutExchange@DeleteExchange 等。

2. 核心注解介紹

注解說明等效的 HTTP 方法
@HttpExchange通用注解,可以指定 URL、方法等。通常用作其他注解的元注解。由 method 屬性指定
@GetExchange用于發(fā)起 HTTP GET 請(qǐng)求。GET
@PostExchange用于發(fā)起 HTTP POST 請(qǐng)求。POST
@PutExchange用于發(fā)起 HTTP PUT 請(qǐng)求。PUT
@DeleteExchange用于發(fā)起 HTTP DELETE 請(qǐng)求。DELETE
@PatchExchange用于發(fā)起 HTTP PATCH 請(qǐng)求。PATCH

這些注解可以作用于接口方法上,并支持豐富的參數(shù)來定義請(qǐng)求的各個(gè)方面。

3. 應(yīng)用場(chǎng)景

@HttpExchange 的應(yīng)用場(chǎng)景非常廣泛,主要集中在需要與外部 RESTful API 或內(nèi)部微服務(wù)進(jìn)行通信的地方:

  1. 微服務(wù)間通信:在微服務(wù)架構(gòu)中,服務(wù) A 需要調(diào)用服務(wù) B 的 API。使用 @HttpExchange 定義一個(gè)客戶端接口,使得調(diào)用就像調(diào)用本地方法一樣簡(jiǎn)單。
  2. 集成第三方 API:當(dāng)你的應(yīng)用需要調(diào)用如支付網(wǎng)關(guān)(Stripe、支付寶)、社交媒體(微信、微博)、地圖服務(wù)(高德、Google Maps)等第三方 API 時(shí),可以為其創(chuàng)建一個(gè)聲明式客戶端。
  3. 替代 RestTemplate/WebClient:在任何你原本打算使用 RestTemplate 或 WebClient 的地方,都可以考慮使用聲明式客戶端,以獲得更簡(jiǎn)潔、更易于維護(hù)的代碼。
  4. 提升代碼可讀性和可測(cè)試性:接口式的定義讓 API 契約清晰可見。同時(shí),因?yàn)橐蕾嚨氖墙涌?,在單元測(cè)試中非常容易進(jìn)行 Mock。

4. 如何使用-完整示例

我們將通過一個(gè)完整的示例來演示如何創(chuàng)建一個(gè)用于管理“用戶”的聲明式 HTTP 客戶端。

步驟 1:添加依賴(Spring Boot 3.x)

確保你的 pom.xml 使用的是 Spring Boot 3.x+。聲明式客戶端功能包含在 spring-web 模塊中,但通常我們會(huì)使用 WebFlux 的 WebClient 作為底層實(shí)現(xiàn)。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

注意:即使你的應(yīng)用不是響應(yīng)式的,也可以使用 WebClient。你也可以配置為使用 RestTemplate(已標(biāo)記為廢棄)或其它 HTTP 客戶端。

步驟 2:定義聲明式客戶端接口

我們創(chuàng)建一個(gè) UserServiceClient 接口,它對(duì)應(yīng)一個(gè)遠(yuǎn)程的用戶服務(wù) API。

// 使用 @HttpExchange 注解在接口上,定義所有方法的公共路徑
@HttpExchange(url = "/api/v1/users", accept = "application/json", contentType = "application/json")
public interface UserServiceClient {
    /**
     * 獲取所有用戶 - GET /api/v1/users
     */
    @GetExchange // 等價(jià)于 @HttpExchange(method = "GET")
    List<User> getAllUsers();
    /**
     * 根據(jù)ID獲取用戶 - GET /api/v1/users/{id}
     * 使用 @PathVariable 注解路徑參數(shù)
     */
    @GetExchange("/{id}")
    User getUserById(@PathVariable("id") Long id);
    /**
     * 創(chuàng)建新用戶 - POST /api/v1/users
     * 使用 @RequestBody 注解請(qǐng)求體
     */
    @PostExchange
    User createUser(@RequestBody User user);
    /**
     * 更新用戶信息 - PUT /api/v1/users/{id}
     */
    @PutExchange("/{id}")
    User updateUser(@PathVariable("id") Long id, @RequestBody User user);
    /**
     * 刪除用戶 - DELETE /api/v1/users/{id}
     * 返回 void 或特定的響應(yīng)對(duì)象
     */
    @DeleteExchange("/{id}")
    void deleteUser(@PathVariable("id") Long id);
    /**
     * 搜索用戶 - GET /api/v1/users/search?name={name}
     * 使用 @RequestParam 注解查詢參數(shù)
     */
    @GetExchange("/search")
    List<User> searchUsers(@RequestParam String name);
}
// 用戶實(shí)體類
@Data // 使用 Lombok 簡(jiǎn)化 getter/setter
@AllArgsConstructor
@NoArgsConstructor
class User {
    private Long id;
    private String name;
    private String email;
}

步驟 3:配置和啟用客戶端

在配置類或主應(yīng)用類中,使用 @EnableWebClients 注解,并通過 WebClient.Builder 來創(chuàng)建客戶端 Bean。

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
@EnableWebClients // 啟用聲明式 HTTP 客戶端功能
public class WebConfig {
    @Bean
    public UserServiceClient userServiceClient(WebClient.Builder builder) {
        // 1. 創(chuàng)建 WebClient 實(shí)例,指定基礎(chǔ) URL
        WebClient webClient = builder
                .baseUrl("http://jsonplaceholder.typicode.com") // 一個(gè)免費(fèi)的測(cè)試 API
                .build();
        // 2. 創(chuàng)建 HttpServiceProxyFactory
        HttpServiceProxyFactory factory = HttpServiceProxyFactory
                .builder(WebClientAdapter.forClient(webClient))
                .build();
        // 3. 創(chuàng)建客戶端代理實(shí)例
        return factory.createClient(UserServiceClient.class);
    }
}

步驟 4:在 Service 或 Controller 中注入并使用

現(xiàn)在,你可以像使用普通的 Spring Bean 一樣,在任何地方注入 UserServiceClient 并調(diào)用其方法。

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@RequiredArgsConstructor
public class MyBusinessService {
    private final UserServiceClient userServiceClient;
    public void processUserData() {
        // 調(diào)用遠(yuǎn)程 API 就像調(diào)用本地方法一樣
        List<User> allUsers = userServiceClient.getAllUsers();
        System.out.println("All users: " + allUsers);
        User userById = userServiceClient.getUserById(1L);
        System.out.println("User with ID 1: " + userById);
        // ... 其他業(yè)務(wù)邏輯
    }
}

5. 高級(jí)特性

錯(cuò)誤處理:你可以注冊(cè)自定義的 ExchangeFilterFunction 到 WebClient 上來全局處理錯(cuò)誤。

WebClient webClient = builder
    .baseUrl("http://localhost:8080")
    .filter((request, next) -> {
        return next.exchange(request)
            .onStatus(HttpStatusCode::isError, response -> {
                // 處理 4xx/5xx 錯(cuò)誤
                return Mono.error(new RuntimeException("API call failed: " + response.statusCode()));
            });
    })
    .build();

請(qǐng)求/響應(yīng)攔截器:同樣使用 ExchangeFilterFunction 來添加認(rèn)證頭、記錄日志等。

.filter((request, next) -> {
    ClientRequest filteredRequest = ClientRequest.from(request)
            .header("Authorization", "Bearer " + myAuthToken)
            .build();
    return next.exchange(filteredRequest);
})

自定義 HTTP 客戶端:底層不限于 WebClient,Spring 抽象了 HttpClient 接口,可以適配其他實(shí)現(xiàn)(如 JDK 的 HttpClient,Apache HttpClient 等)。

6. 總結(jié)

特性優(yōu)點(diǎn)
簡(jiǎn)潔性極大減少了 HTTP 調(diào)用的模板代碼。
可讀性接口清晰地定義了 API 契約。
可維護(hù)性中心化配置(如基礎(chǔ) URL、攔截器)使維護(hù)更簡(jiǎn)單。
可測(cè)試性易于 Mock,方便單元測(cè)試。
類型安全參數(shù)和返回值都是強(qiáng)類型的,減少了運(yùn)行時(shí)錯(cuò)誤。

總而言之,@HttpExchange 注解是 Spring 生態(tài)中進(jìn)行 HTTP 客戶端編程的一次重大飛躍。它提供了一種類型安全、聲明式且高度可配置的方式來消費(fèi) HTTP API,是開發(fā)現(xiàn)代化 Spring 應(yīng)用程序時(shí)不可或缺的工具。 對(duì)于新項(xiàng)目,強(qiáng)烈建議使用它來代替?zhèn)鹘y(tǒng)的 RestTemplate。

以上就是Spring元注解@HttpExchange聲明式調(diào)用HTTP的詳細(xì)內(nèi)容,更多關(guān)于Spring @HttpExchange的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Intellij IDEA中一次性折疊所有Java代碼的快捷鍵設(shè)置

    Intellij IDEA中一次性折疊所有Java代碼的快捷鍵設(shè)置

    這篇文章主要介紹了Intellij IDEA中一次性折疊所有Java代碼的快捷鍵設(shè)置,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • springboot接收前端參數(shù)的四種方式圖文詳解

    springboot接收前端參數(shù)的四種方式圖文詳解

    Spring Boot可以通過多種方式接收前端傳遞的數(shù)據(jù),下面這篇文章主要給大家介紹了關(guān)于springboot接收前端參數(shù)的四種方式,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-11-11
  • Nexus存儲(chǔ)庫(kù)管理器搭建-Maven私服詳解

    Nexus存儲(chǔ)庫(kù)管理器搭建-Maven私服詳解

    這篇文章主要介紹了Nexus存儲(chǔ)庫(kù)管理器搭建-Maven私服,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-06-06
  • springboot實(shí)現(xiàn)對(duì)注解的切面案例

    springboot實(shí)現(xiàn)對(duì)注解的切面案例

    這篇文章主要介紹了springboot實(shí)現(xiàn)對(duì)注解的切面過程,首先定義一個(gè)注解、再編寫對(duì)注解的切面只是記錄的執(zhí)行時(shí)間和打印方法,可以實(shí)現(xiàn)其他邏輯,需要的朋友可以參考一下
    2022-01-01
  • IDEA中thymeleaf語(yǔ)法沒有提示的問題及解決

    IDEA中thymeleaf語(yǔ)法沒有提示的問題及解決

    這篇文章主要介紹了IDEA中thymeleaf語(yǔ)法沒有提示的問題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • 詳解關(guān)于java文件下載文件名亂碼問題解決方案

    詳解關(guān)于java文件下載文件名亂碼問題解決方案

    這篇文章主要介紹了詳解關(guān)于java文件下載文件名亂碼問題解決方案,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • 詳解Spring Cloud 熔斷機(jī)制--斷路器

    詳解Spring Cloud 熔斷機(jī)制--斷路器

    這篇文章主要介紹了詳解Spring Cloud 熔斷機(jī)制--斷路器,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-04-04
  • 如何通過一張圖搞懂springBoot自動(dòng)注入原理

    如何通過一張圖搞懂springBoot自動(dòng)注入原理

    這篇文章主要給大家介紹了關(guān)于如何通過一張圖搞懂springBoot自動(dòng)注入原理的相關(guān)資料,文中通過圖文以及實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-02-02
  • springboot cloud使用eureka整合分布式事務(wù)組件Seata 的方法

    springboot cloud使用eureka整合分布式事務(wù)組件Seata 的方法

    這篇文章主要介紹了springboot cloud使用eureka整合分布式事務(wù)組件Seata 的方法 ,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-05-05
  • Go?Java算法猜數(shù)字游戲示例詳解

    Go?Java算法猜數(shù)字游戲示例詳解

    這篇文章主要為大家介紹了Go?Java算法猜數(shù)字游戲示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08

最新評(píng)論

翼城县| 兴义市| 兰坪| 孝昌县| 鄂托克前旗| 军事| 满洲里市| 南康市| 青田县| 太仆寺旗| 阜城县| 阿瓦提县| 保山市| 清远市| 南康市| 邢台市| 简阳市| 正阳县| 长阳| 永德县| 湖口县| 读书| 桂阳县| 武邑县| 罗江县| 泊头市| 美姑县| 卓资县| 孝感市| 同仁县| 本溪市| 息烽县| 赞皇县| 定远县| 会泽县| 新河县| 信丰县| 名山县| 武邑县| 常山县| 九江市|