ClientHttpRequestFactory org/springframework/http/client/ClientHttpRequestFactory.java /** * Factory for {@link ClientHttpRequest */ @FunctionalInterface public interface ClientHttpRequestFactory { /** * Create a new {@link ClientHttpRequest *
The returned request can be written to, and then executed by calling * {@link ClientHttpRequest org/springframework/http/client/ClientHttpRequest.java public interface ClientHttpRequest extends HttpRequest * Obtained via an calling of the {@link ClientHttpRequest#execute()}.
this.executed, "ClientHttpRequest already executed"); } /** * Abstract template method http/client/SimpleStreamingAsyncClientHttpRequest.java /** * {@link org.springframework.http.client.ClientHttpRequest /org/springframework/http/client/Netty4ClientHttpRequest.java /** * {@link ClientHttpRequest} implementation extends AbstractAsyncClientHttpRequest implements ClientHttpRequest { private final Bootstrap bootstrap private final HttpMethod method; private final ByteBufOutputStream body; public Netty4ClientHttpRequest
ClientHttpRequestFactoryorg/springframework/http/client/ClientHttpRequestFactory.java/** * Factory for {@link ClientHttpRequest since 3.0 */@FunctionalInterfacepublic interface ClientHttpRequestFactory {/** * Create a new {@link ClientHttpRequest and HTTP method. *
The returned request can be written to, and then executed by calling * {@link ClientHttpRequest HTTP method to execute * @return the created request * @throws IOException in case of I/O errors */ClientHttpRequest interface ClientHttpRequest extends HttpRequest, HttpOutputMessage {/** * Execute this request, resulting
try { //核心是createRequest构建的request中包含什么逻辑 ClientHttpRequest request = createRequest(url responseExtractor.extractData(response) : null); } //...}protected ClientHttpRequest createRequest (URI url, HttpMethod method) throws IOException { ClientHttpRequest request = getRequestFactory(). = null, "No standard HTTP method"); ClientHttpRequest delegate = requestFactory.createRequest
required"); ClientHttpResponse response = null; Object var14; try { // 创建请求 ClientHttpRequest return var14; } HttpAccessor 创建请求 public abstract class HttpAccessor { ... // 省略代码无数 protected ClientHttpRequest URI url, HttpMethod method) throws IOException { // 使用 ClientHttpRequestFactory 创建请求 ClientHttpRequest return request; } } ClientHttpRequestFactory接口的具体实现,如:SimpleClientHttpRequestFactory 创建请求 public ClientHttpRequest this.openConnection(uri.toURL(), this.proxy); this.prepareConnection(connection, httpMethod.name()); return (ClientHttpRequest
ClientHttpResponse response = null; try { //创建请求对象--ClientHttpRequest只提供了一个execute接口,该接口完成具体请求执行过程 //该接口分别有UrlConnection,HttpClient,OkHttp相关支持的实现类 ClientHttpRequest request = createRequest(url 那么如何知道当前应该使用何种类型的ClientHttpRequest实现呢? RestTemplate将该工作交给ClientHttpRequestFactory负责处理,createRequest方法中我们也可以看到: protected ClientHttpRequest ClientHttpRequest delegate = requestFactory.createRequest(request.getURI(), method); ...
Tips:请注意区分RestTemplate和RedisTemplate哦~ ClientHttpRequestFactory 它是个函数式接口,用于根据URI和HttpMethod创建出一个ClientHttpRequest 来发送请求~ ClientHttpRequest它代表请求的客户端,该接口继承自HttpRequest、HttpOutputMessage,只有一个ClientHttpResponse execute ,这样调用其execute()方法就可以发送rest请求了~ ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws 等等属性的一些get/set // 超时信息啥的都是保存在`RequestConfig`里的 @Override public ClientHttpRequest createRequest( 若开启缓存功能(有开关可控),会使用BufferingClientHttpRequestWrapper包装原来的ClientHttpRequest。
Assert.notNull(method, "HttpMethod is required"); ClientHttpResponse response = null; try { ClientHttpRequest 创建请求 下面我们来看看它的createRequest(url, method)方法,从上面的继承关系来看,这里的createRequest是执行的HttpAccessor这个类 protected ClientHttpRequest createRequest(URI url, HttpMethod method) throws IOException { ClientHttpRequest request = getRequestFactory this.interceptors = interceptors; this.method = method; this.uri = uri; } 2、执行请求 回到最上面的方法代码: ClientHttpRequest = null, "No standard HTTP method"); ClientHttpRequest delegate = requestFactory.createRequest(request.getURI
createRequest->request.execute->handleResponse HttpAccessor#createRequest 其中createRequest对Http请求进行了封装 protected ClientHttpRequest createRequest(URI url, HttpMethod method) throws IOException { // 使用工厂构造,该工厂被InterceptingHttpAccessor重写 ClientHttpRequest = null, "No standard HTTP method"); // RestTemplate的requestFactory构建底层HTTP请求客户端 ClientHttpRequest (body, outputStream)); } else { StreamUtils.copy(body, delegate.getBody()); } } // ClientHttpRequest // RestTemplate的SimpleClientHttpRequestFactory构建底层HTTP请求客户端 // 根据是否具有bufferRequestBody选择不同的策略 ClientHttpRequest
>[] argumentsTypes, Object result) throws Throwable { ClientHttpRequest clientHttpRequest = (ClientHttpRequest ) result; if (clientHttpRequest instanceof AbstractClientHttpRequest) { AbstractClientHttpRequest httpRequest = (AbstractClientHttpRequest) clientHttpRequest; //将traceId追加到header头当中 RuntimeContextManager.CarrierItem clientHttpRequest) { CarrierItem carrierItem = get(); clientHttpRequest.getHeaders().remove(ConstName.HEAD_KEY ); while (carrierItem.hasNext()) { carrierItem = carrierItem.next; clientHttpRequest.getHeaders().add
因此我在org.springframework.http.client.reactive.ClientHttpRequest的构造方法处也设置了一个拦截点,负责讲span信息放置到request中进行跨链传输 argumentsTypes, MethodInterceptResult result) throws Throwable { ClientHttpRequest clientHttpRequest = (ClientHttpRequest) allArguments[0]; ContextCarrier contextCarrier = (ContextCarrier contextCarrier.items(); while (next.hasNext()) { next = next.next(); clientHttpRequest.getHeaders
用于操作请求头和body,在请求发出前执行;ResponseExtractor:解析/提取HTTP响应的数据,而且不需要担心异常和资源的关闭 RequestCallback.doWithRequest(ClientHttpRequest )说白了就是拿到ClientHttpRequest后对他进行继续处理~ RestTemplate的acceptHeaderRequestCallback、httpEntityCallback这些方法可以设置它 protected ClientHttpRequest createRequest(URI url, HttpMethod method) throws IOException { ClientHttpRequest InterceptingClientHttpRequestFactory工厂它产生的ClientHttpRequest是InterceptingClientHttpRequest,然而它就会执行拦截器的拦截方法喽 ResponseExtractor<T> responseExtractor) throws RestClientException { ClientHttpResponse response = null; ClientHttpRequest
然后,我们可以实现 RequestCallback 来自定义 Range 请求头来恢复下载: restTemplate.execute( FILE_URL, HttpMethod.GET, clientHttpRequest -> clientHttpRequest.getHeaders().set( "Range", String.format("bytes=%d-%d", file.length(),
org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.http.client.ClientHttpRequest 替换成我们的IP url = replaceUrl(url); log.info("替换后的请求路径:{}", url); ClientHttpRequest
this.clientFactory = clientFactory; } @Override @SuppressWarnings("deprecation") public ClientHttpRequest httpMethod.name()); return new RibbonHttpRequest(originalUri, verb, client, clientConfig); } } ClientHttpRequest
org.springframework.context.annotation.Configuration; import org.springframework.http.HttpHeaders; import org.springframework.http.client.ClientHttpRequest
这个接口的实现可以注册到RestTemplate ,以修改传出的ClientHttpRequest和/或传入的ClientHttpResponse 。
HttpRequestFactory就是InterceptingClientHttpRequestFactory 其createRequest方法如下 @Override protected ClientHttpRequest requestFactory, this.interceptors, uri, httpMethod); } 可以看到RestTemplate中的doExecute()最终会执行request.execute() ClientHttpRequest return requestExecution.execute(this, bufferedOutput); } 在InterceptingRequestExecution中的execute函数 注意到ClientHttpRequest = null, "No standard HTTP method"); ClientHttpRequest delegate = requestFactory.createRequest SimpleClientHttpRequestFactory(); ... } 这里的request.getURI其实是调用的ServiceRequestWrapper中的getURI方法 ClientHttpRequest
EurekaClientHttpRequestFactory extends SimpleClientHttpRequestFactory{ @Override public ClientHttpRequest
4、自定义template 4.1、自定义HTTP源 ClientHttpRequestFactory是Spring定义的一个接口,用于生产ClientHttpRequest对象,RestTemplate