如何注册商标名称以及logo,在线优化网站,WordPress文字导航功能插件,北京网站建设设计公司首先明确两个事情#xff1a;请求对象#xff0c;连接对象
我们知道你要是想发起一个请求#xff0c;需要指定两个环节内容#xff0c;一个是请求内容对象(request)#xff0c;一个是连接内容对象(httpClient) 它们两个的作用我们在下面会看到
简要分析源码
1.先说一下…首先明确两个事情请求对象连接对象
我们知道你要是想发起一个请求需要指定两个环节内容一个是请求内容对象(request)一个是连接内容对象(httpClient) 它们两个的作用我们在下面会看到
简要分析源码
1.先说一下结论spring所有的核心代码都在doxxx()方法里面而http请求的核心代码在doExecute()中。
# 我们平时会写这个一个方法去开启http请求调用
restTemplate.postForObject(url,httpEntity, xxx.class);# 往里钻
Nullablepublic T T postForObject(String url, Nullable Object request, ClassT responseType, Object... uriVariables) throws RestClientException {RequestCallback requestCallback this.httpEntityCallback(request, responseType);HttpMessageConverterExtractorT responseExtractor new HttpMessageConverterExtractor(responseType, this.getMessageConverters(), this.logger);return this.execute(url, HttpMethod.POST, requestCallback, responseExtractor, (Object[])uriVariables);}#继续钻发现了doxxx()方法
Nullablepublic T T execute(String url, HttpMethod method, Nullable RequestCallback requestCallback, Nullable ResponseExtractorT responseExtractor, Object... uriVariables) throws RestClientException {URI expanded this.getUriTemplateHandler().expand(url, uriVariables);return this.doExecute(expanded, method, requestCallback, responseExtractor);}#看看实现我们会发现有一个创建request的操作
Nullableprotected T T doExecute(URI url, Nullable HttpMethod method, Nullable RequestCallback requestCallback, Nullable ResponseExtractorT 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;}# 我们发现所有的request对象都是通过factory创建的不同的factory会创建不同的request对象
# 因为目前我们位于抽象类HttpAccessor中所以我们要继续往实现类追踪getRequestFactory()方法
protected ClientHttpRequest createRequest(URI url, HttpMethod method) throws IOException {ClientHttpRequest request this.getRequestFactory().createRequest(url, method);this.initialize(request);if (this.logger.isDebugEnabled()) {this.logger.debug(HTTP method.name() url);}return request;}# 此时我们位于InterceptingHttpAccessor抽象类中继续往下追踪就是RestInterceptors类了没有重写getRequestFactory()方法所以我们要重点关注InterceptingHttpAccessor抽象类中的重写逻辑
public ClientHttpRequestFactory getRequestFactory() {ListClientHttpRequestInterceptor interceptors this.getInterceptors();if (!CollectionUtils.isEmpty(interceptors)) {ClientHttpRequestFactory factory this.interceptingRequestFactory;if (factory null) {// 如果有interceptors则融合父类的factory和interceptors返回一个新的factory来覆盖原有父类factoryfactory new InterceptingClientHttpRequestFactory(super.getRequestFactory(), interceptors);this.interceptingRequestFactory (ClientHttpRequestFactory)factory;}return (ClientHttpRequestFactory)factory;} else {// 如果没有则interceptors则直接用父类中的factoryreturn super.getRequestFactory();}}至此我们可以得到以下结论如果想对原有请求进行扩展我们需要从两个对象进行下手factoryinterceptor。
接下来我们看一下factory和interceptor两个类中都有什么内容
#factory
public class HttpComponentsClientHttpRequestFactory implements ClientHttpRequestFactory, DisposableBean {// 重点关注连接对象private HttpClient httpClient;Nullableprivate RequestConfig requestConfig;private boolean bufferRequestBody true;Nullableprivate BiFunctionHttpMethod, URI, HttpContext httpContextFactory;
}#interceptor
public interface ClientHttpRequestInterceptor {// 重点关注request对象ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException;
}我们可以发现在factory中我们可以对连接对象进行修改在interceptor中可以对请求对象进行修改我们回归下文章开头一个请求的两个组成部分我们已经发现了。接下来就演示下不同场景应该怎么使用这两种对象。
场景1添加固定请求头
分析请求头内容属于请求对象所以我们通过interceptor来实现
Configuration
public class RestTemplateConfig {/*** restTemplate*/ConditionalOnMissingBeanBeanpublic RestTemplate restTemplate(ClientHttpRequestFactory factory) {RestTemplate restTemplate new RestTemplate();ClientHttpRequestInterceptor clientHttpRequestInterceptor new ClientHttpRequestInterceptor() {Overridepublic ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)throws IOException {request.getHeaders().set(X-ID, );request.getHeaders().set(X-APPKEY, );return execution.execute(request, body);}};restTemplate.setInterceptors(Collections.singletonList(clientHttpRequestInterceptor));return restTemplate;}
}场景二添加请求证书
分析请求头内容属于连接对象所以我们通过factory来实现
public static HttpComponentsClientHttpRequestFactory generateHttpRequestFactory() {TrustStrategy acceptingTrustStrategy (x509Certificates, authType) - true;SSLContext sslContext null;try {sslContext SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy)// 增加请求证书.loadKeyMaterial(ks, keyStorePassword.toCharArray()).setProtocol(TLSv1.2).build();} catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) {log.error(generateHttpRequestFactory failed:, e);}SSLConnectionSocketFactory connectionSocketFactory new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());HttpClientBuilder httpClientBuilder HttpClients.custom();httpClientBuilder.setSSLSocketFactory(connectionSocketFactory);CloseableHttpClient httpClient httpClientBuilder.build();HttpComponentsClientHttpRequestFactory factory new HttpComponentsClientHttpRequestFactory();factory.setHttpClient(httpClient);factory.setConnectTimeout(15000);factory.setReadTimeout(5000);return factory;
}当然两者可以同时存在
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {// 修改factoryRestTemplate restTemplate new RestTemplate(generateHttpRequestFactory());ClientHttpRequestInterceptor clientHttpRequestInterceptor new ClientHttpRequestInterceptor() {Overridepublic ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)throws IOException {request.getHeaders().set(X-HW-ID, com.huawei.osec);request.getHeaders().set(X-HW-APPKEY, /D2QodV7Lu2EUk4D9HEUsQ);return execution.execute(request, body);}};// 修改interceptorrestTemplate.setInterceptors(Collections.singletonList(clientHttpRequestInterceptor));return restTemplate;}