Http Interface
https://docs.spring.io/spring-framework/reference/web/webflux-http-interface-client.html
在 Spring6.0 中,新增了 HTTP Interface,它允许开发者将 HTTP 服务定义为具有 HTTP 方法的 Java 接口。然后,你可以生成一个实现该接口并执行这些交换的代理。这有助于简化 HTTP 远程访问,并提供选择 API 风格(如同步或响应式)的额外灵活性。
快速开始
首先,使用 @HttpExchange
方法创建接口:
public interface RepositoryService {
@GetExchange("/todos/{id}")
ToDo getTodo(@PathVariable("id") Integer id);
}
现在,你可以创建一个在调用时执行请求的代理:
RestClient
RestClient restClient = RestClient.builder().baseUrl("https://jsonplaceholder.typicode.com").build();
RestClientAdapter adapter = RestClientAdapter.create(restClient);
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();
RepositoryService service = factory.createClient(RepositoryService.class);
Todo todo = service.getTodo(1);
WebClient
如果你选择使用 WebClient 作为 HTTP 客户端,那么你的 Http Interface 中方法的返回类型应该是 Publisher 类型(例如 Mono 或 Flux):
WebClient webClient = WebClient.builder().baseUrl("https://jsonplaceholder.typicode.com").build();
WebClientAdapter adapter = WebClientAdapter.create(webClient);
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();
RepositoryService service = factory.createClient(RepositoryService.class);
service.getTodo(1).subscribe(System.out::println);
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);
Todo todo = service.getTodo(1);
@HttpExchange
也可以用于类级别,类级别的配置将应用于所有方法:
@HttpExchange(url = "/todos/{id}")
public interface RepositoryService {
@GetExchange
ToDo getTodo(@PathVariable("id") Integer id);
}
返回值
HTTP Interface 支持的返回值取决于开发者底层选择的客户端。
适配了
HttpExchangeAdapter
的客户端,如RestClient
和RestTemplate
支持同步返回值:
void
执行给定的请求。
HttpHeaders
执行给定的请求并返回响应标头。
ResponseEntity
执行给定的请求并返回 ResponseEntity
状态和标题。
ResponseEntity
执行给定的请求,将响应内容解码为声明的返回类型,并返回 ResponseEntity
状态、标题和解码后的正文。
T
执行给定的请求并将响应内容解码为声明的返回类型。
适配了
ReactorHttpExchangeAdapter
的客户端,如WebClient
支持上述所有功能以及响应式。下表显示了Reactor
类型,但你也可以使用通过ReactiveAdapterRegistry
支持的其他响应式类型:
Mono<Void>
执行给定的请求,并发布响应内容(如果有)。
Mono<HttpHeaders>
执行给定的请求,释放响应内容(如果有),并返回响应标头。
Mono<T>
执行给定的请求并将响应内容解码为声明的返回类型。
Flux<T>
执行给定的请求并将响应内容解码为声明的元素类型的流。
Mono<ResponseEntity<Void>>
执行给定的请求,并释放响应内容(如果有),并返回 ResponseEntity
状态和标头。
Mono<ResponseEntity<T>>
执行给定的请求,将响应内容解码为声明的返回类型,并返回ResponseEntity
状态、标题和解码后的正文。
Mono<ResponseEntity<Flux<T>>
执行给定的请求,将响应内容解码为声明元素类型的流,并返回ResponseEntity
包含状态、标题和解码的响应主体流的内容。
默认情况下,使用 ReactorHttpExchangeAdapter
的同步返回值的超时时间取决于底层 HTTP 客户端的配置。你也可以在适配器级别设置 blockTimeout
值,建议依赖底层 HTTP 客户端的超时设置,因为它在更低的层级操作并提供更多的控制。
错误处理
要定制错误响应处理,开发者需要配置低层 HTTP 客户端的错误处理。
RestClient
默认情况下,RestClient
会将 4xx
和 5xx
响应视为错误,并抛出 RestClientException
异常。你可以使用 RestClient.Builder.defaultStatusHandler
方法自定义错误处理:
RestClient restClient = RestClient.builder()
.defaultStatusHandler(HttpStatusCode::isError, (request, response) -> ...)
.build();
RestClientAdapter adapter = RestClientAdapter.create(restClient);
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();
RestTemplate
默认情况下,RestTemplate
会将 4xx
和 5xx
响应视为错误,抛出 RestClientException
异常。你可以使用 ResponseErrorHandler
自定义错误处理:
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(myErrorHandler);
RestTemplateAdapter adapter = RestTemplateAdapter.create(restTemplate);
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();
WebClient
默认情况下,WebClient
会将 4xx
和 5xx
响应视为错误,并抛出 WebClientResponseException
异常。你可以使用 WebClient.Builder.defaultStatusHandler
方法自定义错误处理:
WebClient webClient = WebClient.builder()
.defaultStatusHandler(HttpStatusCode::isError, resp -> ...)
.build();
WebClientAdapter adapter = WebClientAdapter.create(webClient);
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(adapter).build();
最后更新于
这有帮助吗?