在 Spring 6.1 中,添加了一个新的同步 web 客户端 RestClient,提供更现代化的 fluent API,所以我们能在 spring mvc 里获得与 webflux 一样的 web 请求的编码体验(再加上 project loom 的支持,webflux 还有存在的意义么?)
创建 RestClient RestClient 可以用过 create() 方法直接简单的创建,也可以通过 builder() 构建。在 builder() 中,我们可以传入一些配置或者默认参数,这对于我们统一请求规范有很大的帮助
1 2 3 4 5 6 7 8 9 10 11 RestClient  defaultClient  =  RestClient.create();RestClient  customClient  =  RestClient.builder()   .requestFactory(new  HttpComponentsClientHttpRequestFactory ())   .messageConverters(converters -> converters.add(new  MyCustomMessageConverter ()))   .baseUrl("https://example.com" )   .defaultUriVariables(Map.of("variable" , "foo" ))   .defaultHeader("My-Header" , "Foo" )   .requestInterceptor(myCustomInterceptor)   .requestInitializer(myCustomInitializer)   .build();
 
 
使用 RestClient 1 2 3 4 5 6 Pet  pet  =  restClient.post()   .uri("https://petclinic.example.com/pets/new" )    .contentType(APPLICATION_JSON)    .body(pet)    .retrieve()   .body(Pet.class);
 
RestClient 的 API 与 WebClient 的 API 很相似,除了返回值, WebClient 返回的是 Mono、Flux,而 RestClient 返回的是实体类(毕竟是同步请求,会阻塞直接获取结果)。
HTTP Interface 事实上在使用 Spring Boot 中,如果我们需要用到请求数据,一般而言,我们都会引入第三方的库,比如 OpenFeign、Retrofit 等,毕竟这些框架提供了通过接口的方式,定义请求,但现在 Spring 本身也支持了,或许在大部分项目中,我们可以使用 Spring 的而不在需要引入第三方的库。
1 2 3 4 5 6 7 8 interface  RepositoryService  { 	@GetExchange("/repos/{owner}/{repo}")  	Repository getRepository (@PathVariable  String owner, @PathVariable  String repo) ; 	 }
 
1 2 3 4 5 6 7 8 9 10 11 @HttpExchange(url = "/repos/{owner}/{repo}", accept = "application/vnd.github.v3+json") interface  RepositoryService  { 	@GetExchange  	Repository 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) ; }
 
在 RestClient 我们可以通过以下配置,来获得代理实现
1 2 3 4 5 RestClient  restClient  =  RestClient.builder().baseUrl("https://api.github.com/" ).build();RestClientAdapter  adapter  =  RestClientAdapter.create(restClient);HttpServiceProxyFactory  factory  =  HttpServiceProxyFactory.builderFor(adapter).build();RepositoryService  service  =  factory.createClient(RepositoryService.class);
 
当然不仅仅是 RestClient, 在 WebClient 和 RestTemplate 中,我们也同样可以通过接口来定义请求。
1 2 3 4 5 WebClient  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);
 
1 2 3 4 5 6 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);