Java调用外部REST请求的几种方式

1 restTemplate — spring 提供特点:
1、RestOperations 提供了各种封装方法,非常方便直接将返回转成实体类 。
2、默认使用JDK 的HttpURLConnection进行通信,但是可以通过RestTemplate.setRequestFactory 切换到不同的HTTP源:如Apache HttpComponents、Netty、OkHttp 。
3、支持同步、异步请求;
4、支持更多的定制,比如拦截器等 。
ps:支持 get 请求,参数是 body 的形式 。
【Java调用外部REST请求的几种方式】参考:https://www.huaweicloud.com/articles/7f32ca1acff12162ce8d3bace872ae04.html
国外知名博客Baeldung的博客 The Guide to RestTemplate: https://www.baeldung.com/rest-template
1.1 底层是JAVA的HttpURLConnection(默认使用,可以定制)所有的请求都需要执行 doExecute() 方法
@Nullableprotected <T> T doExecute(URI url, @Nullable HttpMethod method, @Nullable RequestCallback requestCallback, @Nullable ResponseExtractor<T> responseExtractor) throws RestClientException {Assert.notNull(url, "URI is required");Assert.notNull(method, "HttpMethod is required");ClientHttpResponse response = null;Object var14;try {// 创建请求ClientHttpRequest request = this.createRequest(url, method);if (requestCallback != null) {requestCallback.doWithRequest(request);}response = request.execute();this.handleResponse(url, method, response);var14 = responseExtractor != null ? responseExtractor.extractData(response) : null;} catch (IOException var12) {String resource = url.toString();String query = url.getRawQuery();resource = query != null ? resource.substring(0, resource.indexOf(63)) : resource;throw new ResourceAccessException("I/O error on " + method.name() + " request for "" + resource + "": " + var12.getMessage(), var12);} finally {if (response != null) {response.close();}}return var14;}HttpAccessor 创建请求
public abstract class HttpAccessor {... // 省略代码无数protected ClientHttpRequest createRequest(URI url, HttpMethod method) throws IOException {// 使用 ClientHttpRequestFactory 创建请求ClientHttpRequest request = this.getRequestFactory().createRequest(url, method);if (this.logger.isDebugEnabled()) {this.logger.debug("HTTP " + method.name() + " " + url);}return request;}}ClientHttpRequestFactory接口的具体实现,如:SimpleClientHttpRequestFactory 创建请求
public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {// 使用 HttpURLConnection 创建请求HttpURLConnection connection = this.openConnection(uri.toURL(), this.proxy);this.prepareConnection(connection, httpMethod.name());return (ClientHttpRequest)(this.bufferRequestBody ? new SimpleBufferingClientHttpRequest(connection, this.outputStreaming) : new SimpleStreamingClientHttpRequest(connection, this.chunkSize, this.outputStreaming));}1.2 post 请求,返回直接封装为实体RestTemplate restTemplate = new RestTemplate();HttpEntity<Foo> request = new HttpEntity<>(new Foo("bar"));Foo foo = restTemplate.postForObject(fooResourceUrl, request, Foo.class);assertThat(foo, notNullValue());assertThat(foo.getName(), is("bar"));1.3 get请求,但是参数是body形式一般 get 请求,不支持 body 传参 。
参考:https://stackoverflow.com/questions/43421126/how-to-use-httpclient-to-send-content-in-body-of-get-request/68812976#68812976

HTTP GET with a body is a somewhat unconventional construct that falls in a gray area of the HTTP specification - the end result is that many older pieces of software either cannot handle such a request at all, or will explicitly reject it because they believe it to be malformed.
带有body参数的HTTP GET是一种非传统的构造,属于HTTP规范的灰色区域 。最终的结果是,许多旧的软件要么根本不能处理这样的请求,要么会明确拒绝,因为他们认为它是格式错误的请求 。
/** * 注意:get请求,但是参数是body形式 * * @param url * @param paramBody * @return */private String getWithBody(String url, Map<String, Object> paramBody) {HttpHeaders httpHeaders = new HttpHeaders();httpHeaders.setContentType(MediaType.AppLICATION_JSON);httpHeaders.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));HttpEntity requestEntity = new HttpEntity(JsonUtil.of(paramBody), httpHeaders);RestTemplate template = getTemplate();ResponseEntity response = template.exchange(url, HttpMethod.GET, requestEntity, String.class);Object result = response.getBody();logger.info("/invokeThirdPartyRequest/getWithBody/result/[{}]", result.toString());return result.toString();}/** * 获取 RestTemplate * * @return */private RestTemplate getTemplate() {RestTemplate restTemplate = new RestTemplate();//修改restTemplate的RequestFactory使其支持Get携带body参数restTemplate.setRequestFactory(new HttpComponentsClientRestfulHttpRequestFactory());return restTemplate;}


推荐阅读