聊聊HttpComponentsHttpInvokerRequestExecutor

本文主要研究一下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;@Nullableprivate 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 mergereturn 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)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/93358.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Qt图形视图框架】自定义QGraphicsItem和QGraphicsView,实现鼠标(移动、缩放)及键盘事件、右键事件

自定义QGraphicsItem和QGraphicsView 说明示例myitem.hmyitem.cppmyview.hmyview.cpp调用main.cpp 效果 说明 在使用Qt的图形视图框架实现功能时&#xff0c;一般会在其基础上进行自定义功能实现。 如&#xff1a;滚轮对场景的缩放&#xff0c;鼠标拖动场景中的项&#xff0c;…

用python表格初级尝试

Excel&#xff0c;我的野心 当我输入3,2 就表示在第3行第2列。的单元格输入数据input输入表头 &#xff08;input内除了/&#xff0c;空格 回车 标点符号等 全部作为单元格分隔符&#xff09;由我设置input输入的是行or列 给选项 1. 行 2. 列默认回车或没输入值是列由我设置起…

数据结构 B树 B+树 B*树 特性与规则说明 图解

文章目录 前言B树基本规则B树的数据插入&#xff08;文字描述图解&#xff09;B树数据查找B树效率分析B树的作用B树基本规则B树 与 B树对比B*树基本规则B*树 与 B树对比拓展 前言 B树基本规则 每个节点最多有m个子节点&#xff0c;其中m是一个正整数。根节点除外&#xff0c;其…

云原生Kubernetes:K8S集群各组件服务重启

目录 一、理论 1.各组件服务重启命令 一、理论 1.各组件服务重启命令 &#xff08;1&#xff09;Master节点Node节点共同服务 systemctl restart etcd systemctl daemon-reload systemctl enable flanneld systemctl restart flanneld &#xff08;2&#xff09;Master节…

聊聊并发编程——线程池

目录 Java线程池 处理流程 线程池主要参数 常见的拒绝策略 execute和submit区别 关闭线程池 常见的线程池 newSingleThreadExecutor newFixedThreadPool newCachedThreadPool newScheduledThreadPool 线程池的状态 Java线程池 运用场景最多的并发框架&#xff0c;…

阿里巴巴K8S集成seata

正文 在K8S集成seata&#xff0c;官方配置 代码 apiVersion: v1 kind: Service metadata:name: seata-servernamespace: wmz-devlabels:k8s-app: seata-server spec:type: NodePortports:- port: 8091nodePort: 30091protocol: TCPname: httpselector:k8s-app: seata-server-…

Java练习题-键盘录入字符串实现大小写转换

✅作者简介&#xff1a;CSDN内容合伙人、阿里云专家博主、51CTO专家博主、新星计划第三季python赛道Top1&#x1f3c6; &#x1f4c3;个人主页&#xff1a;hacker707的csdn博客 &#x1f525;系列专栏&#xff1a;Java练习题 &#x1f4ac;个人格言&#xff1a;不断的翻越一座又…

idea清空缓存类

解决办法 网上有很多是让你去清空什么maven依赖&#xff0c;但假如这个项目是你不可以大刀阔斧的话 可以清空idea缓存 选择 Invalidate 开头的 然后全选 运行重启idea OK

Linux系统编程系列之线程

一、什么是线程 线程&#xff08;Thread&#xff09;是计算机中的基本执行单元&#xff0c;是操作系统调度的最小单位。线程是进程内的一个独立执行流程&#xff0c;一个进程可以包含多个线程&#xff0c;这些线程共享进程的资源&#xff0c;但每个线程都有自己的独立栈空间以及…

Java后端模拟面试,题集①

1.Spring bean的生命周期 实例化 Instantiation属性赋值 Populate初始化 Initialization销毁 Destruction 2.Spring AOP的创建在bean的哪个时期进行的 &#xff08;图片转载自Spring Bean的完整生命周期&#xff08;带流程图&#xff0c;好记&#xff09;&#xff09; 3.MQ如…

基于SSM的选课排课系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

Java 文档注释

Java 文档注释 目录 Java 文档注释 javadoc 标签 文档注释 javadoc输出什么 实例 Java只是三种注释方式。前两种分别是// 和/* */&#xff0c;第三种被称作说明注释&#xff0c;它以/** 开始&#xff0c;以 */结束。 说明注释允许你在程序中嵌入关于程序的信息。你可以使…

2023年中国奶牛平均单产量、奶类产量及发展趋势分析:液态奶市场向高端化发展[图]

2022年&#xff0c;我国奶产业素质稳步提升&#xff0c;全国存栏百头以上规模养殖比例达到72%&#xff0c;同比提高2个百分点。奶牛平均单产9.2吨&#xff0c;较2021年增加500千克&#xff1b;规模牧场95%以上配备全混合日粮搅拌车&#xff0c;原料奶生产100%实现机械化挤奶&am…

3D WEB轻量化引擎HOOPS助力3D测量应用蓬勃发展:效率、精度显著提升

在3D开发工具领域&#xff0c;Tech Soft 3D打造的HOOPS SDK已经崭露头角&#xff0c;成为了全球领先的3D领域开发工具提供商。HOOPS SDK包括四种不同的3D软件开发工具&#xff0c;已成为行业的翘楚。 其中&#xff0c;HOOPS Exchange以其CAD数据转换的能力脱颖而出&#xff0c…

Linux回收内存的时候遇到PageWriteback和PageDirty脏页怎么处理?

概述 我们知道内存回收会遇到各种情况的page,比如正在回写的page(PageWriteback)和脏页(PageDirty)的page,内核会等待PageWriteback完成回写呢,还是说直接跳过正在回写的页面。这两种选择各有优劣,如果等待Writeback完成会影响内存分配性能;如果直接跳过呢可能影响内存…

如何破解压缩包zip解压密码?

Zip压缩包设置了密码&#xff0c;解压的时候就需要输入正确对密码才能顺利解压出文件&#xff0c;正常当我们解压文件或者删除密码的时候&#xff0c;虽然方法多&#xff0c;但是都需要输入正确的密码才能完成。忘记密码就无法进行操作。 那么&#xff0c;忘记了zip压缩包的密…

leetCode 55.跳跃游戏 贪心算法

给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输入…

基于微信小程序的手机在线商城小程序设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言系统主要功能&#xff1a;具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计…

MySql017——组合查询

一、UNION作用 可用UNION操作符来组合数条SQL查询。 二、UNION 使用规则 1、UNION的使用很简单。所需做的只是给出每条SELECT语句&#xff0c;在各条语句之间放上关键字UNION。2、UNION必须由两条或两条以上的SELECT语句组成&#xff0c;语句之间用关键字UNION分隔&#xff…

信息化发展76

数字政府 信息技术的革新改变了人们传统的工作、学习、生活和娱乐方式&#xff0c;同时对政府提供信息服务&#xff0c;公民参与政府民主决策的方式提出了挑战。利用信息技术改进政府工作及服务的效率&#xff0c;形成新的工作方式&#xff0c;这已成为各国政府所关心的问题。…