文档章节

HttpClient4.5使用

xlj44400
 xlj44400
发布于 2016/07/13 18:41
字数 1306
阅读 609
收藏 4

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
47
1
httpclient跳过https请求的验证

一、因为在使用https发送请求的时候会涉及,验证方式。但是这种方式在使用的时候很不方便。特别是在请求外部接口的时候,所以这我写了一个跳过验证的方式。(供参考) 二、加入包,这里用的是...

小不点丶
2017/07/12
0
0
HttpClient4.5 上传文件失败

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

首席程序猿_默
2015/11/05
1K
3
浅谈HttpClient

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

xionghuiCoder
2015/09/15
1K
1
有关于httpclient4.5进行CA证书认证

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

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

没有更多内容

加载失败,请刷新页面

加载更多

Redis的API应用

全局命令 1,查看所有键:keys * set school dongnao set hello world 2,键总数 dbsize //2个键,如果存在大量键,线上禁止使用此指令 3,检查键是否存在:exists key //存在返回1,不存在返...

这很耳东先生
26分钟前
1
0
Java GC机制详解

垃圾收集 Garbage Collection 通常被称为“GC”,本文详细讲述Java垃圾回收机制。 导读: 1、什么是GC 2、GC常用算法 3、垃圾收集器 4、finalize()方法详解 5、总结--根据GC原理来优化代码 ...

编程SHA
28分钟前
1
0
CMD 乱码永久解决方案

创建cmd.reg,内容如下,双击运行导入注册表。 Windows Registry Editor Version 5.00[HKEY_CURRENT_USER\Console\%SystemRoot%_system32_cmd.exe]"CodePage"=dword:0000fde9"FontFamil......

yeahlife
31分钟前
1
0
亿级Web系统搭建:单机到分布式集群

当一个Web系统从日访问量10万逐步增长到1000万,甚至超过1亿的过程中,Web系统承受的压力会越来越大,在这个过程中,我们会遇到很多的问题。为了解决这些性能压力带来问题,我们需要在Web系统...

onedotdot
35分钟前
1
0
Linux 命令优先级 —— alias、function、内部命令(make)

Linux 命令优先级 —— alias、function、内部命令(make) make 新建Makefile文件,在里面输入如下内容; # Makefile内容all:@echo "Make Command echo : Hello " 保存,执行 which make ,...

雪落青山
36分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部