美文网首页
聊聊HttpComponentsHttpInvokerReque

聊聊HttpComponentsHttpInvokerReque

作者: go4it | 来源:发表于2023-10-02 09:16 被阅读0次

本文主要研究一下HttpComponentsHttpInvokerRequestExecutor

HttpComponentsHttpInvokerRequestExecutor

org/springframework/remoting/httpinvoker/HttpComponentsHttpInvokerRequestExecutor.java

public class HttpComponentsHttpInvokerRequestExecutor extends AbstractHttpInvokerRequestExecutor {

    private static final int DEFAULT_MAX_TOTAL_CONNECTIONS = 100;

    private static final int DEFAULT_MAX_CONNECTIONS_PER_ROUTE = 5;

    private static final int DEFAULT_READ_TIMEOUT_MILLISECONDS = (60 * 1000);


    private HttpClient httpClient;

    @Nullable
    private RequestConfig requestConfig;


    /**
     * Create a new instance of the HttpComponentsHttpInvokerRequestExecutor with a default
     * {@link HttpClient} that uses a default {@code org.apache.http.impl.conn.PoolingClientConnectionManager}.
     */
    public HttpComponentsHttpInvokerRequestExecutor() {
        this(createDefaultHttpClient(), RequestConfig.custom()
                .setSocketTimeout(DEFAULT_READ_TIMEOUT_MILLISECONDS).build());
    }

    private static HttpClient createDefaultHttpClient() {
        Registry<ConnectionSocketFactory> schemeRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.getSocketFactory())
                .register("https", SSLConnectionSocketFactory.getSocketFactory())
                .build();

        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(schemeRegistry);
        connectionManager.setMaxTotal(DEFAULT_MAX_TOTAL_CONNECTIONS);
        connectionManager.setDefaultMaxPerRoute(DEFAULT_MAX_CONNECTIONS_PER_ROUTE);

        return HttpClientBuilder.create().setConnectionManager(connectionManager).build();
    }

    //......
}

HttpComponentsHttpInvokerRequestExecutor继承了AbstractHttpInvokerRequestExecutor,其构造器提供了createDefaultHttpClient方法,默认注册了http及https的socketFactory,然后创建了PoolingHttpClientConnectionManager,默认maxTotal为100,defaultMaxPerRoute为5,其requestConfig默认设置了socketTimeout为60s

doExecuteRequest

    protected RemoteInvocationResult doExecuteRequest(
            HttpInvokerClientConfiguration config, ByteArrayOutputStream baos)
            throws IOException, ClassNotFoundException {

        HttpPost postMethod = createHttpPost(config);
        setRequestBody(config, postMethod, baos);
        try {
            HttpResponse response = executeHttpPost(config, getHttpClient(), postMethod);
            validateResponse(config, response);
            InputStream responseBody = getResponseBody(config, response);
            return readRemoteInvocationResult(responseBody, config.getCodebaseUrl());
        }
        finally {
            postMethod.releaseConnection();
        }
    }

HttpComponentsHttpInvokerRequestExecutor实现了AbstractHttpInvokerRequestExecutor定义的doExecuteRequest方法,执行createHttpPost创建postMethod,然后设置requestBody,之后设置setRequestBody,接着执行executeHttpPost,验证response,读取responseBody,最后在finally里头执行postMethod.releaseConnection()

createHttpPost

    protected HttpPost createHttpPost(HttpInvokerClientConfiguration config) throws IOException {
        HttpPost httpPost = new HttpPost(config.getServiceUrl());

        RequestConfig requestConfig = createRequestConfig(config);
        if (requestConfig != null) {
            httpPost.setConfig(requestConfig);
        }

        LocaleContext localeContext = LocaleContextHolder.getLocaleContext();
        if (localeContext != null) {
            Locale locale = localeContext.getLocale();
            if (locale != null) {
                httpPost.addHeader(HTTP_HEADER_ACCEPT_LANGUAGE, locale.toLanguageTag());
            }
        }

        if (isAcceptGzipEncoding()) {
            httpPost.addHeader(HTTP_HEADER_ACCEPT_ENCODING, ENCODING_GZIP);
        }

        return httpPost;
    }

    protected RequestConfig createRequestConfig(HttpInvokerClientConfiguration config) {
        HttpClient client = getHttpClient();
        if (client instanceof Configurable) {
            RequestConfig clientRequestConfig = ((Configurable) client).getConfig();
            return mergeRequestConfig(clientRequestConfig);
        }
        return this.requestConfig;
    }

    private RequestConfig mergeRequestConfig(RequestConfig defaultRequestConfig) {
        if (this.requestConfig == null) {  // nothing to merge
            return defaultRequestConfig;
        }

        RequestConfig.Builder builder = RequestConfig.copy(defaultRequestConfig);
        int connectTimeout = this.requestConfig.getConnectTimeout();
        if (connectTimeout >= 0) {
            builder.setConnectTimeout(connectTimeout);
        }
        int connectionRequestTimeout = this.requestConfig.getConnectionRequestTimeout();
        if (connectionRequestTimeout >= 0) {
            builder.setConnectionRequestTimeout(connectionRequestTimeout);
        }
        int socketTimeout = this.requestConfig.getSocketTimeout();
        if (socketTimeout >= 0) {
            builder.setSocketTimeout(socketTimeout);
        }
        return builder.build();
    }

createHttpPost先是创建HttpPost,然后设置requestConfig,接着设置locale及gzipEncoding

setRequestBody

    protected void setRequestBody(
            HttpInvokerClientConfiguration config, HttpPost httpPost, ByteArrayOutputStream baos)
            throws IOException {

        ByteArrayEntity entity = new ByteArrayEntity(baos.toByteArray());
        entity.setContentType(getContentType());
        httpPost.setEntity(entity);
    }

setRequestBody方法这里创建ByteArrayEntity,设置contentType,然后赋值给httpPost

executeHttpPost

    protected HttpResponse executeHttpPost(
            HttpInvokerClientConfiguration config, HttpClient httpClient, HttpPost httpPost)
            throws IOException {

        return httpClient.execute(httpPost);
    }

executeHttpPost直接通过httpClient.execute方法执行post请求

getResponseBody

    protected InputStream getResponseBody(HttpInvokerClientConfiguration config, HttpResponse httpResponse)
            throws IOException {

        if (isGzipResponse(httpResponse)) {
            return new GZIPInputStream(httpResponse.getEntity().getContent());
        }
        else {
            return httpResponse.getEntity().getContent();
        }
    }

    protected boolean isGzipResponse(HttpResponse httpResponse) {
        Header encodingHeader = httpResponse.getFirstHeader(HTTP_HEADER_CONTENT_ENCODING);
        return (encodingHeader != null && encodingHeader.getValue() != null &&
                encodingHeader.getValue().toLowerCase().contains(ENCODING_GZIP));
    }

getResponseBody方法会先判断是否是gzip,是的话创建GZIPInputStream,否则直接取httpResponse.getEntity().getContent()

小结

HttpComponentsHttpInvokerRequestExecutor是org.springframework.remoting.httpinvoker包里头的,它继承了继承了AbstractHttpInvokerRequestExecutor,演示了httpclient的基本配置(默认maxTotal为100,defaultMaxPerRoute为5,其requestConfig默认设置了socketTimeout为60s)及其使用(创建request、设置entity、执行请求、解析response)。

相关文章

  • 聊聊…聊聊?

    世界不大,一座城市里,用高楼大厦圈出来的的圈子更小了… 心再大,也会被城市里喧嚣的汽笛压抑自己 不记得有多久没有好...

  • 聊聊聊

    今天主要的时间是和阿q过的,非常开心我们有了这么一次聊天! 我觉得自己不孤单了。我俩目前拥有的感情非常相似,是比较...

  • 无聊聊聊

  • 聊聊,聊聊选择

    今早梦到一杯豆浆15元,我给自己的孩子买了一杯50元的奶茶,对她感叹“在我们那个年代一杯奶茶才10元”孩子问我那么...

  • 聊聊,聊聊闲时

    有段时间着了迷一样的看伍迪艾伦电影,印象最深的就是电影开场他一张大脸挤满了屏幕,絮絮叨叨两分钟,正片开始。 后来得...

  • 37

    今晚不想你睡 想和你聊聊聊聊聊到天天天天天长地久

  • 那个我以为很酷的男生

    熄了 灯,朋友打电话来聊天,聊了好久好久… 聊聊过去,聊聊现在,聊聊未来,聊聊别人,也聊聊自己… 一晃我们过了二字...

  • 悠然自得——二舅家游记(下)

    我们一起聊聊工作,聊聊生活,聊聊城市,聊聊乡村,聊聊猪场,聊聊门前那条黑背。我不争气的扒在窗口,安安静静地看着它。...

  • 我一直不缺母爱20210106

    元旦,儿子放月假。 其实我儿子每次放假回家都会和我聊聊天,聊聊学校,聊聊老师,聊聊同学,聊聊他自己,没有着重点,都...

  • 聊聊人生 聊聊理想

    今天跟老朋友约着去省图书馆看了书。然后我又去借了两本书回来。觉得一天下来还挺充实的,挺喜欢这种生活的。可能我也比较...

网友评论

      本文标题:聊聊HttpComponentsHttpInvokerReque

      本文链接:https://www.haomeiwen.com/subject/fxrsbdtx.html