一、简单使用
这里没有涉及任何连接方面的配置,直接使用,需要看源码才知道RestTemplate是如何进行网络连接的。
根据经验,我们知道,发起网络通信,通常是有需要有网络连接工具类的,我们熟知的有:
1、JDK自带的java.net.URLConnection
2、org.apache.http.client.HttpClient
3、其他一些http工具类
RestTemplate也不例外。
package com.wang.pub.util;
import com.alibaba.fastjson2.JSON;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;
import java.util.Collections;
import java.util.Map;
/**
* @author cheng
* @date 2024/3/19 21:58
* description
*/
public class RestTemplateUtil2 {
public static final RestTemplate REST_TEMPLATE = new RestTemplate();
public static String postJson(String url, Object param) {
return exchange(url, HttpMethod.POST, param);
}
private static String exchange(String url, HttpMethod method, Object param) {
return exchange(url, method, genJsonHeaders(null), param);
}
private static String exchange(String url, HttpMethod method, HttpHeaders headers, Object param) {
String jsonParam = JSON.toJSONString(param);
headers = headers != null ? headers : genJsonHeaders(null);
HttpEntity<String> requestEntity = new HttpEntity<>(jsonParam, headers);
ResponseEntity<String> responseEntity = REST_TEMPLATE.exchange(url, method, requestEntity, String.class);
return responseEntity.getBody();
}
public static HttpHeaders genJsonHeaders(Map<String, String> headerMap) {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.setContentType(MediaType.APPLICATION_JSON);
buildHeaders(headers, headerMap);
return headers;
}
private static void buildHeaders(HttpHeaders httpHeaders, Map<String, String> headerMap) {
if (!CollectionUtils.isEmpty(headerMap)) {
headerMap.forEach(httpHeaders::add);
}
}
}
这里的createRequest()就调用到父类HttpAccessor了。
public class RestTemplate extends InterceptingHttpAccessor implements RestOperations {
@Override
@Nullable
public <T> T execute(String url, HttpMethod method, @Nullable RequestCallback requestCallback,
@Nullable ResponseExtractor<T> responseExtractor, Object... uriVariables) throws RestClientException {
URI expanded = getUriTemplateHandler().expand(url, uriVariables);
return doExecute(expanded, method, requestCallback, responseExtractor);
}
@Nullable
protected <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;
try {
ClientHttpRequest request = createRequest(url, method);
if (requestCallback != null) {
requestCallback.doWithRequest(request);
}
response = request.execute();
handleResponse(url, method, response);
return (responseExtractor != null ? responseExtractor.extractData(response) : null);
}
catch (IOException ex) {
String resource = url.toString();
String query = url.getRawQuery();
resource = (query != null ? resource.substring(0, resource.indexOf('?')) : resource);
throw new ResourceAccessException("I/O error on " + method.name() +
" request for \"" + resource + "\": " + ex.getMessage(), ex);
}
finally {
if (response != null) {
response.close();
}
}
}
}
RestTemplate的有关继承关系如下,上面是父类,下面是子类
org.springframework.http.client.support.HttpAccessor
org.springframework.http.client.support.InterceptingHttpAccessor
org.springframework.web.client.RestTemplate
RestTemplate把发送请求的功能封装到
org.springframework.http.client.ClientHttpRequest
把制造ClientHttpRequest的功能封装工厂
org.springframework.http.client.ClientHttpRequestFactory
默认的请求制造工厂是
org.springframework.http.client.SimpleClientHttpRequestFactory
public abstract class HttpAccessor {
/** Logger available to subclasses. */
protected final Log logger = HttpLogging.forLogName(getClass());
private ClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
}
public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory, AsyncClientHttpRequestFactory {
@Override
public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {
HttpURLConnection connection = openConnection(uri.toURL(), this.proxy);
prepareConnection(connection, httpMethod.name());
if (this.bufferRequestBody) {
return new SimpleBufferingClientHttpRequest(connection, this.outputStreaming);
}
else {
return new SimpleStreamingClientHttpRequest(connection, this.chunkSize, this.outputStreaming);
}
}
}
二、简单使用的弊端
最大的弊端是配置都是默认的,不能适应应用各自环境,最明显的问题就是在高并发下会有性能问题,这个是生产实际出现的问题,不用怀疑。
三、优化版
想要进行优化,先要找到性能瓶颈在哪里。