在 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);