文档章节

HttpClient4.5使用

xlj44400
 xlj44400
发布于 2016/07/13 18:41
字数 1306
阅读 376
收藏 3
点赞 0
评论 0

HttpClient简介

HttpClient 是 Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient支持的功能如下:

  • 支持Http0.9、Http1.0和Http1.1协议。
  • 实现了Http全部的方法(GET,POST,PUT,HEAD 等)。
  • 支持HTTPS协议。
  • 支持代理服务器。
  • 提供安全认证方案。
  • 提供连接池以便重用连接。
  • 连接管理器支持多线程应用。支持设置最大连接数,同时支持设置每个主机的最大连接数,发现并关闭过期的连接。
  • 在http1.0和http1.1中利用KeepAlive保持长连接。

以前是commons-httpclient,后面被Apache HttpComponents取代,目前版本4.5.x,我们现在用的就是4.5版本

HttpClient连接池使用

为什么要用Http连接池:

1、降低延迟:如果不采用连接池,每次连接发起Http请求的时候都会重新建立TCP连接(经历3次握手),用完就会关闭连接(4次挥手),如果采用连接池则减少了这部分时间损耗

2、支持更大的并发:如果不采用连接池,每次连接都会打开一个端口,在大并发的情况下系统的端口资源很快就会被用完,导致无法建立新的连接
  • 默认http协议:
private static final Charset CHAR_SET = Charset.forName("utf-8");
private static PoolingHttpClientConnectionManager cm;

	public void init() {
		cm = new PoolingHttpClientConnectionManager();
		cm.setMaxTotal(50);
		cm.setDefaultConnectionConfig(ConnectionConfig.custom()
				.setCharset(CHAR_SET).build());
		SocketConfig socketConfig = SocketConfig.custom().setSoTimeout(30000)
				.setSoReuseAddress(true).build();
		cm.setDefaultSocketConfig(socketConfig);
		// HttpProtocolParams.setContentCharset(httpParams, "UTF-8");
		// HttpClientParams.setCookiePolicy(httpParams, "ignoreCookies");
		// HttpConnectionParams.setConnectionTimeout(httpParams, 30000);
		// HttpConnectionParams.setSoTimeout(httpParams, 30000);
		httpClient = HttpClientBuilder.create().setConnectionManager(cm)
				.build();
	}

	public CloseableHttpClient getHttpClient() {
		int timeout=2;
		RequestConfig config = RequestConfig.custom()
				.setConnectTimeout(timeout * 1000) //设置连接超时时间,单位毫秒
				//.setConnectionRequestTimeout(timeout * 1000) //设置从connect Manager获取Connection 超时时间,单位毫秒
				.setSocketTimeout(timeout * 1000).build(); //请求获取数据的超时时间,单位毫秒
		CloseableHttpClient _httpClient = HttpClients.custom()
				.setConnectionManager(cm).setDefaultRequestConfig(config)
				.build();
		if(cm!=null&&cm.getTotalStats()!=null) { //打印连接池的状态		
			LOGGER.info("now client pool {}",cm.getTotalStats().toString());
		}
		return _httpClient;
	}

	public String post(String url, Map<String, String> params) {
		HttpPost post = new HttpPost(url);
		String resp = null;
		try {
			if(params != null){
				List<NameValuePair> nvps = new ArrayList<NameValuePair>();
				for (Map.Entry<String, String> param : params.entrySet()) {
					nvps.add(new BasicNameValuePair(param.getKey(), param.getValue()));
				}
				post.setEntity(new UrlEncodedFormEntity(nvps, CHAR_SET));
			}
			
			try {
				HttpResponse response = httpClient.execute(post);
				InputStream input = response.getEntity().getContent();
				resp = IOUtils.toString(input);
			} catch (ClientProtocolException e) {
				LOGGER.error(e.getMessage(), e);
			} catch (IOException e) {
				LOGGER.error(e.getMessage(), e);
			} catch (Exception e) {
				LOGGER.error(e.getMessage(), e);
			}
		} finally {
			if (post != null)
				post.releaseConnection();
		}
		return resp;
	}
  • https协议:
public class HttpConnectionManager {

    PoolingHttpClientConnectionManager cm = null;
    
    public void init() {
        LayeredConnectionSocketFactory sslsf = null;
        try {
            sslsf = new SSLConnectionSocketFactory(SSLContext.getDefault());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create()
                .register("https", sslsf)
                .register("http", new PlainConnectionSocketFactory())
                .build();
        cm =new PoolingHttpClientConnectionManager(socketFactoryRegistry);
        cm.setMaxTotal(200);
        cm.setDefaultMaxPerRoute(20);
    }

    public CloseableHttpClient getHttpClient() {       
        CloseableHttpClient httpClient = HttpClients.custom()
                .setConnectionManager(cm)
                .build();          
        
        /*
        //如果不采用连接池就是这种方式获取连接
        CloseableHttpClient httpClient = HttpClients.createDefault();
        */
        return httpClient;
    }
}
  • httpClient使用
catch (Exception e) {
            logger.error("ufile send error e:",e);
            try {
                if (resEntity != null && resEntity.getContent() != null) {
                    resEntity.getContent().close();
                }
            } catch (IllegalStateException | IOException e1) {
                logger.error("ufile send error e1:",e1);
            } finally {
                if (getMethod!=null) {
                    getMethod.releaseConnection();
                }
                /*if (httpClient!=null) { //连接池使用的时候不能关闭连接,否则下次使用会抛异常 java.lang.IllegalStateException: Connection pool shut down
                    try {
                        httpClient.close();
                    } catch (IOException e2) {
                        logger.error("ufile httpclient close error e2:",e2);
                    }
                }*/
            }
        }
  • 连接池使用注意事项:
    1. 连接池中连接都是在发起请求的时候建立,并且都是长连接
    
    2. HttpResponse input.close();作用就是将用完的连接释放,下次请求可以复用,这里特别注意的是,如果不使用in.close();而仅仅使用httpClient.close();结果就是连接会被关闭,并且不能被复用,这样就失去了采用连接池的意义。
    
    3. 连接池释放连接的时候,并不会直接对TCP连接的状态有任何改变,只是维护了两个Set,leased和avaliabled,leased代表被占用的连接集合,avaliabled代表可用的连接的集合,释放连接的时候仅仅是将连接从leased中remove掉了,并把连接放到avaliabled集合中
    

打印的状态:

INFO c.m.p.u.h.HttpClientUtils[72] - now client pool [leased: 0; pending: 0; available: 0; max: 50]

leased :the number of persistent connections tracked by the connection manager currently being used to execute requests.  
  
available :the number idle persistent connections.  
  
pending : the number of connection requests being blocked awaiting a free connection.  
  
max: the maximum number of allowed persistent connections.  

HttpClient 4.5超时设置

4.5版本中,这两个参数的设置都抽象到了RequestConfig中,由相应的Builder构建,具体的例子如下:

CloseableHttpClient httpclient = HttpClients.createDefault();  
HttpGet httpGet = new HttpGet("http://stackoverflow.com/");  
RequestConfig requestConfig = RequestConfig.custom()  
      .setConnectTimeout(5000).setConnectionRequestTimeout(1000)  
      .setSocketTimeout(5000).build();  
httpGet.setConfig(requestConfig);  
CloseableHttpResponse response = httpclient.execute(httpGet);  
System.out.println("得到的结果:" + response.getStatusLine());//得到请求结果  
HttpEntity entity = response.getEntity();//得到请求回来的数据
  • setConnectTimeout:设置连接超时时间,单位毫秒。ConnectTimeoutException
  • setConnectionRequestTimeout:设置从connect Manager获取Connection 超时时间,单位毫秒。这个属性是新加的属性,因为目前版本是可以共享连接池的。ConnectionPoolTimeout
  • setSocketTimeout:请求获取数据的超时时间,单位毫秒。 如果访问一个接口,多少时间内无法返回数据,就直接放弃此次调用。SocketTimeoutException
  • 上面3个时间4.5版本默认是-1,就是不限,如果不设置就会一直等待

© 著作权归作者所有

共有 人打赏支持
xlj44400
粉丝 1
博文 3
码字总数 3826
作品 0
高级程序员
问下httpclient怎么能对服务端进行断点调试

我是用httpclient4.5写的客户端和服务端进行交互,但是客户端的statusCode老是报500,估计是服务端代码出错了,但是不知道怎么能通过运行客户端代码对服务端进行断点调试有没有会的啊。或者有...

冬夜的星空 ⋅ 2017/08/05 ⋅ 1

HttpClient4.5 上传文件失败

@JFinal 你好,想跟你请教个问题: 我使用httpclient上传附件的时候报Separation boundary was not specified 下面是方法方法的代码 public String sendHttpClientUpload(String path, Stri...

首席程序猿_默 ⋅ 2015/11/05 ⋅ 3

浅谈HttpClient

HttpClient简介 HttpClient 是 Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。Htt...

xionghuiCoder ⋅ 2015/09/15 ⋅ 1

有关于httpclient4.5进行CA证书认证

鄙人做了个小项目,在eclipse搭建了一个客户端项目和一个服务端项目,客户端将文件流和印章图片流上传至服务端,服务端将印章盖在文件后化为流返回到客户端,客户端再输出到本地,功能是做出...

冬夜的星空 ⋅ 2017/07/31 ⋅ 5

HttpClient4.5 使用http连接池发送http请求深度示例

HttpClient 3.x,4.x都提供http连接池管理器,当使用了请求连接池管理器(比如PoolingHttpClientConnectionManager)后,HttpClient就可以同时执行多个线程的请求了。 hc3.x和4.x的早期版本,提...

gaolu ⋅ 2015/10/21 ⋅ 1

httpclient4.5 上传带有中文的文件乱码

方法一: 加上这两行代码 meb.setCharset(Charset.forName("utf-8")); meb.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); 方法二:(还没试,应该可行) 对包含中文路径url进行编码后在传 ...

小雪纷飞 ⋅ 02/04 ⋅ 0

大神救命啊,httpclient4.5 中文附件上传 日志中 filename="??.text" 乱码无法上传。

MultipartEntity reqEntity = new MultipartEntity(); FileBody bin=null; if(newuserid.get("file1") != null){ bin= new FileBody((File)newuserid.get("file1"),ContentType.create("appl......

luo_yangyang ⋅ 2015/07/17 ⋅ 2

没有更多内容

加载失败,请刷新页面

加载更多
zblog2.3版本的asp系统是否可以超越卢松松博客的流量[图]

最近访问zblog官网,发现zlbog-asp2.3版本已经进入测试阶段了,虽然正式版还没有发布,想必也不久了。那么作为aps纵横江湖十多年的今天,blog2.2版本应该已经成熟了,为什么还要发布这个2.3...

原创小博客 ⋅ 今天 ⋅ 0

聊聊spring cloud的HystrixCircuitBreakerConfiguration

序 本文主要研究一下spring cloud的HystrixCircuitBreakerConfiguration HystrixCircuitBreakerConfiguration spring-cloud-netflix-core-2.0.0.RELEASE-sources.jar!/org/springframework/......

go4it ⋅ 今天 ⋅ 0

二分查找

二分查找,也称折半查找、二分搜索,是一种在有序数组中查找某一特定元素的搜索算法。搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;如果某一特定元素大于...

人觉非常君 ⋅ 今天 ⋅ 0

VS中使用X64汇编

需要注意的是,在X86项目中,可以使用__asm{}来嵌入汇编代码,但是在X64项目中,再也不能使用__asm{}来编写嵌入式汇编程序了,必须使用专门的.asm汇编文件来编写相应的汇编代码,然后在其它地...

simpower ⋅ 今天 ⋅ 0

ThreadPoolExecutor

ThreadPoolExecutor public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, ......

4rnold ⋅ 昨天 ⋅ 0

Java正无穷大、负无穷大以及NaN

问题来源:用Java代码写了一个计算公式,包含除法和对数和取反,在页面上出现了-infinity,不知道这是什么问题,网上找答案才明白意思是负的无穷大。 思考:为什么会出现这种情况呢?这是哪里...

young_chen ⋅ 昨天 ⋅ 0

前台对中文编码,后台解码

前台:encodeURI(sbzt) 后台:String param = URLDecoder.decode(sbzt,"UTF-8");

west_coast ⋅ 昨天 ⋅ 0

实验楼—MySQL基础课程-挑战3实验报告

按照文档要求创建数据库 sudo sercice mysql startwget http://labfile.oss.aliyuncs.com/courses/9/createdb2.sqlvim /home/shiyanlou/createdb2.sql#查看下数据库代码 代码创建了grade......

zhangjin7 ⋅ 昨天 ⋅ 0

一起读书《深入浅出nodejs》-node模块机制

node 模块机制 前言 说到node,就不免得提到JavaScript。JavaScript自诞生以来,经历了工具类库、组件库、前端框架、前端应用的变迁。通过无数开发人员的努力,JavaScript不断被类聚和抽象,...

小草先森 ⋅ 昨天 ⋅ 0

Java桌球小游戏

其实算不上一个游戏,就是两张图片,不停的重画,改变ball图片的位置。一个左右直线碰撞的,一个有角度碰撞的。 左右直线碰撞 package com.bjsxt.test;import javax.swing.*;import j...

森林之下 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部