日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

1. 介紹

Spring 6是一個非常強大的框架,它提供了許多工具和接口來簡化遠程接口調用。其中,WebClient、RestTemplate、HTTP Interface和RestClient是四種方式。

WebClient是Spring 5中新引入的一個接口基于響應式,它提供了一種更簡單、更靈活的方式來調用遠程接口。與RestTemplate相比,WebClient更加現代化,具有更好的性能和更低的內存占用。

RestTemplate是Spring 3中引入的一個接口,它提供了一種更加簡單、更加直觀的方式來調用遠程接口。雖然WebClient是更現代化的選擇,但RestTemplate仍然是一種常用的遠程接口調用方式。

HTTP Interface將 HTTP 服務定義為一個 JAVA 接口,其中包含用于 HTTP 交換的注解方法。然后,你可以生成一個實現該接口并執行交換的代理。這有助于簡化 HTTP 遠程訪問,因為遠程訪問通常需要使用一個門面來封裝使用底層 HTTP 客戶端的細節。

RestClient是一個同步 HTTP 客戶端,提供現代、流暢的 API。它為 HTTP 庫提供了一個抽象,可以方便地從 Java 對象轉換為 HTTP 請求,并從 HTTP 響應創建對象。

下面分別介紹4個REST接口調用的詳細使用。

2. 遠程接口調用

RestTemplate

RestTemplate 提供了比 HTTP 客戶端庫更高級別的 API。它使調用 REST 端點變得簡單易行。它公開了以下幾組重載方法:

方法

描述

getForObject

通過GET檢索數據。

getForEntity

使用 GET 獲取響應實體(即狀態、標頭和正文)。

headForHeaders

使用 HEAD 讀取資源的所有標頭。

postForLocation

使用 POST 創建新資源,并從響應中返回位置標頭。

postForObject

使用 POST 創建一個新資源,并從響應中返回描述。

postForEntity

使用 POST 創建一個新資源,并從響應中返回描述。

put

使用 PUT 創建或更新資源。

patchForObject

使用 PATCH 更新資源,并返回響應中的描述。請注意,JDK HttpURLConnection 不支持 PATCH,但 Apache HttpComponents 和其他組件支持。

delete

使用 DELETE 刪除指定 URI 上的資源。

optionsForAllow

通過 ALLOW 讀取資源允許使用的 HTTP 方法。

exchange

前述方法的更通用(更少意見)版本,可在需要時提供額外的靈活性。它接受一個 RequestEntity(包括作為輸入的 HTTP 方法、URL、標題和正文),并返回一個 ResponseEntity。

這些方法允許使用參數化類型引用(ParameterizedTypeReference)而不是類(Class)來指定具有泛型的響應類型。

execute

執行請求的最通用方式,可通過回調接口完全控制請求準備和響應提取。

  • 初始化

默認構造函數使用 java.NET.HttpURLConnection 來執行請求。你可以通過 ClientHttpRequestFactory 的實現切換到不同的 HTTP 庫。目前,該程序還內置了對 Apache HttpComponents 和 OkHttp 的支持。示例:

RestTemplate template = new RestTemplate(new HttpComponentsClientHttpRequestFactory());

每個 ClientHttpRequestFactory 都會公開底層 HTTP 客戶端庫的特定配置選項,例如,憑證、連接池和其他細節。

  • URIs

許多 RestTemplate 方法都接受 URI 模板和 URI 模板變量,可以是字符串變量參數,也可以是 Map<String,String>。

String result = restTemplate.getForObject(
    "http://pack.com/users/{userId}", String.class, 666) ;

Map<String, ?>方式:

Map<String, Object> params = Collections.singletonMap("userId", 666);


String result = restTemplate.getForObject(
    "http://pack.com/users/{userId}", String.class, params) ;
  • Headers

可以使用 exchange() 方法指定請求頭,如下例所示:

String uriTemplate = "http://pack.com/users/{userId}";
URI uri = UriComponentsBuilder.fromUriString(uriTemplate).build(42);


RequestEntity<Void> requestEntity = RequestEntity.get(uri)
    .header("x-api-token", "aabbcc")
    .build() ;
ResponseEntity<String> response = template.exchange(requestEntity, String.class);
String responseHeader = response.getHeaders().getFirst("x-version");
String body = response.getBody() ;
  • body

如果你當前CLASSPATH存在MAppingJackson2HttpMessageConverter,那么你可以直接將請求結果映射為你所需要的結果對象,如下示例所示,將目標接口返回值直接轉換為User對象。

User user = restTemplate.getForObject("http://pack.com/users/{userId}", User.class, 666);

默認情況下,RestTemplate 會注冊所有內置的消息轉換器,這決定于你當前類路徑是否有相應的轉換庫。你也可以顯式設置要使用的消息轉換器。默認構造函數如下:

public RestTemplate() {
  this.messageConverters.add(new ByteArrayHttpMessageConverter());
  this.messageConverters.add(new StringHttpMessageConverter());
  this.messageConverters.add(new ResourceHttpMessageConverter(false));
  // ...其它轉換器
  if (jackson2Present) {
    this.messageConverters.add(new MappingJackson2HttpMessageConverter());
  }
  else if (gsonPresent) {
    this.messageConverters.add(new GsonHttpMessageConverter());
  }
  else if (jsonbPresent) {
    this.messageConverters.add(new JsonbHttpMessageConverter());
  }
  // ...其它轉換器
  this.uriTemplateHandler = initUriTemplateHandler();
}

注意:RestTemplate 目前處于維護模式,只接受小改動和錯誤請求。請考慮改用 WebClient。

WebClient

WebClient 是執行 HTTP 請求的非阻塞、反應式客戶端。它在 5.0 中引入,提供了 RestTemplate 的替代方案,支持同步、異步和流場景。

WebClient 支持以下功能:

  1. 非阻塞 I/O。
  2. 反應流反向壓力
  3. 用更少的硬件資源實現高并發。
  4. 利用 Java 8 lambdas 的函數式流暢應用程序接口。
  5. 同步和異步交互。
  6. 服務器上的數據流或服務器下的數據流。

示例:

Mono<Person> result = client.get()
  .uri("/users/{userId}", id).accept(MediaType.APPLICATION_JSON)
  .retrieve()
  .bodyToMono(User.class);

HTTP Interface

Spring Framework 可讓你將 HTTP 服務定義為一個 Java 接口,其中包含用于 HTTP 交換的注解方法。然后,你可以生成一個實現該接口并執行交換的代理。這有助于簡化 HTTP 遠程訪問,因為遠程訪問通常需要使用一個門面來封裝使用底層 HTTP 客戶端的細節。

首先,聲明一個帶有 @HttpExchange 方法的接口:

@HttpExchange(url = "/demos")
public interface DemoInterface {


  @PostExchange("/format3/{id}")
  Users queryUser(@PathVariable Long id);


}

創建一個代理,執行所聲明的 HTTP exchanges:

@Service
public class DemoService {


  private final DemoInterface demoInterface ;


  public DemoService() {
    // 基于響應式調用;你當前的環境需要引入webflux
    WebClient client = WebClient.builder().baseUrl("http://localhost:8088/").build() ;
    HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(client)).build() ;
    this.demoInterface = factory.createClient(DemoInterface.class) ;
  }


  public Users queryUser(Long id) {
    return this.demoInterface.queryUser(id) ;
  }


}

測試接口

@Resource
private DemoService demoService ;




@GetMapping("/{id}")
public Users getUser(@PathVariable("id") Long id) {
  return this.demoService.queryUser(id) ;
}

執行結果

Spring6提供的四種遠程接口調用神器!你知道那種?圖片

支持的方法參數

方法參數

說明

URI

動態設置請求的 URL,覆蓋注解的 url 屬性。

HttpMethod

動態設置請求的 HTTP 方法,覆蓋注解的方法屬性

@RequestHeader

添加一個或多個請求標頭。參數可以是包含多個標頭的 Map<String, ?> 或 MultiValueMap<String, ?>、值集合<?> 或單個值。

@PathVariable

添加一個變量,用于擴展請求 URL 中的占位符。參數可以是包含多個變量的 Map<String, ?> 或單個值。

@RequestBody

提供請求的正文,既可以是要序列化的對象,也可以是 Reactive Streams Publisher(如 Mono、Flux 或通過配置的 ReactiveAdapterRegistry 支持的任何其他異步類型)。

@RequestParam

添加一個或多個請求參數。參數可以是包含多個參數的 Map<String, ?> 或 MultiValueMap<String, ?>、數值集合<?> 或單個數值。

當 "content-type"設置為 "application/x-www-form-urlencoded "時,請求參數將在請求正文中編碼。否則,它們將作為 URL 查詢參數添加。

@RequestPart

添加一個請求部分,它可以是字符串(表單字段)、資源(文件部分)、對象(要編碼的實體,如 JSON)、HttpEntity(部分內容和標頭)、Spring 部分或上述任何部分的 Reactive Streams 發布器。

@CookieValue

添加一個或多個 cookie。參數可以是包含多個 cookie 的 Map<String, ?> 或 MultiValueMap<String, ?>、值集合<?> 或單個值。

支持的返回值

返回值

說明

voidMono<Void>

執行給定的請求,并發布響應內容(如果有)。

HttpHeaders
Mono<HttpHeaders>

執行給定的請求,釋放響應內容(如果有),并返回響應標頭。

<T>Mono<T>

執行給定的請求,并根據聲明的返回類型對響應內容進行解碼。

<T>Flux<T>

執行給定的請求,并將響應內容解碼為已聲明元素類型的數據流。

ResponseEntity<Void>
Mono<ResponseEntity<Void>>

執行給定的請求,釋放響應內容(如果有),并返回一個包含狀態和標頭的 ResponseEntity。

ResponseEntity<T>,
Mono<ResponseEntity<T>>

執行給定的請求,按照聲明的返回類型解碼響應內容,并返回一個包含狀態、標頭和解碼后正文的 ResponseEntity。

Mono<ResponseEntity<Flux<T>>

執行給定的請求,將響應內容解碼為已聲明元素類型的數據流,并返回一個包含狀態、標頭和解碼后的響應正文數據流的 ResponseEntity。

異常處理

默認情況下,WebClient為4xx和5xx HTTP狀態代碼引發WebClientResponseException。要自定義此項,可以注冊響應狀態處理程序,該處理程序應用于通過客戶端執行的所有響應:

WebClient client = WebClient.builder()
    // 狀態碼為4xx或5xx
    .defaultStatusHandler(HttpStatusCode::isError, resp -> Mono.just(new RuntimeException(resp.statusCode().toString() + "請求錯誤")))
    .baseUrl("http://localhost:8088/").build() ;
HttpServiceProxyFactory factory = HttpServiceProxyFactory
    .builder(WebClientAdapter.forClient(client)).build() ;

RestClient

該接口是在Spring6.1.1版本中才有的,是一個同步 HTTP 客戶端,提供現代、流暢的 API。

創建RestClientRestClient 是通過靜態創建方法之一創建的。你還可以使用 builder 獲取帶有更多選項的生成器,例如指定要使用的 HTTP 庫和要使用的消息轉換器,設置默認 URI、默認路徑變量、默認請求頭,或注冊攔截器和初始化器。

創建(或構建)后,RestClient 可由多個線程安全使用。

// 默認通過靜態方法創建
RestClient restClient = RestClient.create();
// 自定義方式
RestClient restClient = RestClient.builder()
  .requestFactory(new HttpComponentsClientHttpRequestFactory())
  // 自定義消息轉換器
  // .messageConverters(converters -> converters.add(new PackCustomMessageConverter()))
  .baseUrl("http://localhost:8088")
  .defaultUriVariables(Map.of("id", "888"))
  .defaultHeader("x-api-token", "aabbcc")
  .requestInterceptor(new ClientHttpRequestInterceptor() {
    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
        throws IOException {
      System.out.println("我是攔截器") ;
      return execution.execute(request, body) ;
    }
  })
  .requestInitializer(new ClientHttpRequestInitializer() {
    @Override
    public void initialize(ClientHttpRequest request) {
      System.out.println("我是初始化器") ;
      request.getHeaders().add("x-version", "1.0.0") ;
    }
  })
  .build() ;

調用及處理返回值

Users users = customClient.get()
  .uri("/demos/users/{id}")
  .retrieve()
  .body(Users.class) ;

post+body請求方式

Users user = new Users();
ResponseEntity<Void> response = restClient.post() 
  .uri("/demos/users") 
  .contentType(APPLICATION_JSON) 
  .body(user) 
  .retrieve()
  .toBodilessEntity() ;

錯誤處理默認情況下,當返回狀態代碼為 4xx 或 5xx 的響應時,RestClient 會拋出 RestClientException 的子類。可以使用 onStatus.RestClientException 命令重寫該行為。

Users users = customClient.get()
  .uri("/demos/users/{id}")
  .retrieve()
  // 處理返回狀態碼為:4xx和5xx
  .onStatus(HttpStatusCode::isError, (request, response) -> {
    throw new RuntimeException(response.getStatusCode().toString() + "請求錯誤") ;
  })
  .body(Users.class) ;

總結:實現遠程接口調用方面的強大功能。無論是使用WebClient、RestTemplate、HTTP Interface還是直接使用RestClient,Spring都提供了豐富的工具和接口來簡化開發者的操作。這些工具和接口不僅具有高性能、低內存占用的優點,而且提供了良好的可擴展性和靈活性,使得開發者可以根據實際需求進行定制化開發。

分享到:
標簽:Spring
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定