> 技术文档 > Spring6.0新特性-HTTP接口:使用@HttpExchange实现更优雅的Http客户端_spring6 postexchange

Spring6.0新特性-HTTP接口:使用@HttpExchange实现更优雅的Http客户端_spring6 postexchange


文章目录

  • 一、概述
  • 二、使用
    • 1、创建接口@HttpExchange方法
    • 2、创建一个在调用方法时执行请求的代理
    • 3、方法参数
    • 4、返回值
    • 5、错误处理
      • (1)为RestClient
      • (2)为WebClient
      • (3)为RestTemplate
  • 注意

一、概述

官方文档:https://docs.spring.io/spring-framework/reference/6.1/integration/rest-clients.html#rest-http-interface

Spring6.0推出了新的HTTP接口(类似Openfeign,但是无法做到根据微服务名称进行负载均衡),Spring框架允许您将HTTP服务定义为Java接口@HttpExchange方法。
可以将这样的接口传递给HttpServiceProxyFactory创建通过HTTP客户端执行请求的代理,例如RestClient或者WebClient。
也可以从实现接口@Controller用于服务器请求处理。

二、使用

1、创建接口@HttpExchange方法

interface RepositoryService {@GetExchange(\"/repos/{owner}/{repo}\")Repository getRepository(@PathVariable String owner, @PathVariable String repo);// more HTTP exchange methods...}

2、创建一个在调用方法时执行请求的代理

// 为RestClientRestClient restClient = RestClient.builder().baseUrl(\"https://api.github.com/\").build();// 适配RestClientAdapter adapter = RestClientAdapter.create(restClient);HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();// 构建接口的代理,可以注册为Bean,直接调用RepositoryService service = factory.createClient(RepositoryService.class);
// 为WebClientWebClient webClient = WebClient.builder().baseUrl(\"https://api.github.com/\").build();WebClientAdapter adapter = WebClientAdapter.create(webClient);HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();RepositoryService service = factory.createClient(RepositoryService.class);
// 为RestTemplate RestTemplate restTemplate = new RestTemplate();restTemplate.setUriTemplateHandler(new DefaultUriBuilderFactory(\"https://api.github.com/\"));RestTemplateAdapter adapter = RestTemplateAdapter.create(restTemplate);HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();RepositoryService service = factory.createClient(RepositoryService.class);
// @HttpExchange在类型级别受支持,它适用于所有方法@HttpExchange(url = \"/repos/{owner}/{repo}\", accept = \"application/vnd.github.v3+json\")interface RepositoryService {@GetExchangeRepository getRepository(@PathVariable String owner, @PathVariable String repo);@PatchExchange(contentType = MediaType.APPLICATION_FORM_URLENCODED_VALUE)void updateRepository(@PathVariable String owner, @PathVariable String repo,@RequestParam String name, @RequestParam String description, @RequestParam String homepage);}

3、方法参数

带注解的HTTP交换方法支持具有以下方法参数的灵活方法签名
Spring6.0新特性-HTTP接口:使用@HttpExchange实现更优雅的Http客户端_spring6 postexchange

4、返回值

支持的返回值取决于底层客户端。

客户适应HttpExchangeAdapter诸如RestClient和RestTemplate支持同步返回值:
Spring6.0新特性-HTTP接口:使用@HttpExchange实现更优雅的Http客户端_spring6 postexchange

客户响应ReactorHttpExchangeAdapter诸如WebClient,支持上述所有功能以及反应性变体。下表显示了反应器类型,但是也可以使用通过ReactiveAdapterRegistry:
Spring6.0新特性-HTTP接口:使用@HttpExchange实现更优雅的Http客户端_spring6 postexchange
默认情况下,同步返回值与ReactorHttpExchangeAdapter取决于底层HTTP客户端的配置。您可以设置一个blockTimeout值,但是我们建议依赖底层HTTP客户机的超时设置,它在较低的级别上运行并提供更多的控制。

5、错误处理

要定制错误响应处理,您需要配置底层HTTP客户端。

(1)为RestClient

默认情况下,RestClient抛出RestClientException对于4xx和5xx HTTP状态代码。要对此进行自定义,请注册一个适用于通过客户端执行的所有响应的响应状态处理程序:

RestClient restClient = RestClient.builder().defaultStatusHandler(HttpStatusCode::isError, (request, response) -> ...).build();RestClientAdapter adapter = RestClientAdapter.create(restClient);HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();

有关更多详细信息和选项(如取消错误状态代码),请参见的JavadocdefaultStatusHandlerRestClient.Builder

(2)为WebClient

默认情况下,WebClient抛出WebClientResponseException对于4xx和5xx HTTP状态代码。要对此进行自定义,请注册一个适用于通过客户端执行的所有响应的响应状态处理程序:

WebClient webClient = WebClient.builder().defaultStatusHandler(HttpStatusCode::isError, resp -> ...).build();WebClientAdapter adapter = WebClientAdapter.create(webClient);HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(adapter).build();

(3)为RestTemplate

默认情况下,RestTemplate抛出RestClientException对于4xx和5xx HTTP状态代码。要对此进行自定义,请注册一个适用于通过客户端执行的所有响应的错误处理程序:

RestTemplate restTemplate = new RestTemplate();restTemplate.setErrorHandler(myErrorHandler);RestTemplateAdapter adapter = RestTemplateAdapter.create(restTemplate);HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();

有关更多详细信息和选项,请参见的JavadocsetErrorHandler在RestTemplate和ResponseErrorHandler等级制度。

注意

  1. HttpEntity标题和正文必须提供给RestClient通过headers(Consumer)和body(Object).
  2. RequestEntity方法、URI、标头和正文必须提供给RestClient通过method(HttpMethod), uri(URI), headers(Consumer)body(Object).
  3. @HttpExchange(url = \"http://order\")是可以替代OpenFeign,实现通过服务名来进行微服务调用负载均衡的!SpringCloud高版本做了适配。