new DefaultHttpClient过时处理建议和HTTP调用后关闭流处理
来源:互联网 发布:java单例 编辑:程序博客网 时间:2024/06/14 08:38
最近写新的调用代码时候,发现项目中new DefaultHttpClient()实例过期很久了,翻了翻另一个生产项目调用端的代码也是如此,于是查阅了些资料,用新版本代码替换了手上项目的代码并且正常测试完、生产上也正常运行完,算是一次补习,特记录下替换过程和调用完后的处理。
1:来看下原来的调用代码,也是最常用的(httpclient版本超过4.2.6):(仅限于引用org.apache.httpcomponents的调用方式)
项目原先用的4.3.1,过了4.2.6就已经过时了,过时代码下面我会标注。
HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost("调用地址"); List<NameValuePair> formparams = new ArrayList<NameValuePair>(); formparams.add(new BasicNameValuePair("参数队列头部", 调用参数)); System.out.println("==== 提交参数 ======" +formparams); UrlEncodedFormEntity uefEntity; try { uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8"); httppost.setEntity(uefEntity); HttpResponse response = httpclient.execute(httppost); HttpEntity entity = response.getEntity(); if(entity!=null){ String results=EntityUtils.toString(entity, "UTF-8"); System.out.println("接口返回值="+results); } EntityUtils.consume(entity); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 关闭连接,释放资源 httpclient.getConnectionManager().shutdown(); }
从4.2.6版本后,原作用类就出现了过时标识注明,看了maven仓更新时间2013-09-04是4.2.6和4.3同时发布的。
2:下面看下DefaultHttpClient的源码:(追溯源码)
* @since 4.0 * * @deprecated (4.3) use {@link HttpClientBuilder}. */ @ThreadSafe @Deprecated public class DefaultHttpClient extends AbstractHttpClient { /** * Creates a new HTTP client from parameters and a connection manager. * * @param params the parameters * @param conman the connection manager */ public DefaultHttpClient( final ClientConnectionManager conman, final HttpParams params) { super(conman, params); }
看得出来为什么过时了还能用,DefaultHttpClient 继承了 AbstractHttpClient,AbstractHttpClient 继承了CloseableHttpClient。
”Creates a new HTTP client from parameters and a connection manager“ ,创建一个HTTP管理连接的一个”动作“类。
”* @deprecated (4.3) use {@link HttpClientBuilder}.“ ,说明从4.3版本后使用httpclientBuilder新的类,类httpclientBuilder的头部介绍:
”* Please note that some settings used by this class can be mutually exclusive and may not apply when building {@link CloseableHttpClient}“,翻译过来是和CloseableHttpClient有互斥性,看到有hostname,ssl安全证书加载这些就知道是中后期才会运行到的,都是在外部封装类运行提交的参数后内部运行的。
这是调式模式下,图中可以看到参数会传递到httpClientBuilder中处理。
综合资料和httpClientBuilder的作用写下新的调用代码(HttpClientBuilder里CloseableHttpClient的build方法):
private static final CloseableHttpClient httpClient; static { RequestConfig config = RequestConfig.custom().setConnectTimeout(60000).setSocketTimeout(15000).build(); httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config).build(); } public static void TestHttpPost(String url, String jsonData) { HttpPost httpPost = new HttpPost("调用地址"); // 拼接参数 List<NameValuePair> list = new ArrayList<NameValuePair>(); list.add(new BasicNameValuePair("参数队列头部", 调用参数)); System.out.println("==== 提交参数 ======" + list); CloseableHttpResponse response = null; try { httpPost.setEntity(new UrlEncodedFormEntity(list)); response = httpClient.execute(httpPost); int statusCode = response.getStatusLine().getStatusCode(); if (statusCode != HttpStatus.SC_OK) { httpPost.abort(); throw new RuntimeException("HttpClient,error status code :" + statusCode); } System.out.println("========HttpResponseProxy:========" + statusCode); HttpEntity entity = response.getEntity(); if (entity != null) { String result = EntityUtils.toString(entity, "UTF-8"); System.out.println("========接口返回=======" + result); } EntityUtils.consume(entity); } catch (Exception e) { e.printStackTrace(); } finally { if (response != null) { try { response.close(); } catch (IOException e) { e.printStackTrace(); } } if (httpClient != null) { try { httpClient.close(); } catch (IOException e) { e.printStackTrace(); } } } }
看AbstractHttpClient 继承了CloseableHttpClient的CloseableHttpClient:
@ThreadSafe //线程安全
public abstract class CloseableHttpClient implements HttpClient, Closeable
不难看出实现了httpclient,那么调用方法有了,还实现了关闭流,说明调用完毕后会做关闭处理。CloseableHttpResponse也替换了原来的HttpResponse ,使用CloseableHttpClient的新版本代码:
CloseableHttpClient httpClient = HttpClients.createDefault(); HttpPost httpPost = new HttpPost(”调用地址“); //拼接参数 List<NameValuePair> list = new ArrayList<NameValuePair>(); list.add(new BasicNameValuePair("参数队列头部", 调用参数)); System.out.println("==== 提交参数 ======" +list); CloseableHttpResponse response = null; try { httpPost.setEntity(new UrlEncodedFormEntity(list)); response = httpClient.execute(httpPost); System.out.println("========HttpResponseProxy:========"+response.getStatusLine()); HttpEntity entity = response.getEntity(); if(entity != null){ String result = EntityUtils.toString(entity, "UTF-8"); System.out.println("========接口返回=======" +result); } EntityUtils.consume(entity); //httpClient.getConnectionManager().shutdown(); } catch (Exception e) { e.printStackTrace(); }finally { if(response != null){ try { response.close(); } catch (IOException e) { e.printStackTrace(); } } if(httpClient != null){ try { httpClient.close(); } catch (IOException e) { e.printStackTrace(); } } }
3:旧版本调用完处理和新版本调用完处理:
先看旧版本的关闭方法,
httpclient.getConnectionManager().shutdown();
只要httpclient开启后,BasicClientConnectionManager里的托管连接connManager初始化,其中shutdown开启 = false,运行完调用shutdown方法变 = true。
Response接收httpEntity返回参数时,EntityUtils.consume(entity);关闭参数流操作。
总结:连接动作关闭,接收参数流关闭。
public static void consume(final HttpEntity entity) throws IOException { if (entity == null) { return; } if (entity.isStreaming()) { final InputStream instream = entity.getContent(); if (instream != null) { instream.close(); } } }
新方法调用后关闭方法,
httpClient.close();
新方法是开启了CloseableHttpClient后,PoolingHttpClientConnectionManager赋值CloseableHttpClient 对象并初始化,shutdown为开启状态。
httpClient.getConnectionManager().shutdown(); 和 httpClient.close(); 都是关闭调用功能,因为实现类都impl实现了Closeable关闭流操作,所以在client端调用哪个方法都是可以关闭的,只是有些方法被注明过时了,用新方法不用担心出现@Deprecated标记。
4:总结:
因为每次调用的不同,不及时关闭在大请求量下就需要谨慎设计代码的安全性了。
- new DefaultHttpClient过时处理建议和HTTP调用后关闭流处理
- DefaultHttpClient过时的替换
- 20170825_malloc和new申请内存失败后的处理
- HttpClient请求DefaultHttpClient过时替换
- 关于DefaultHttpClient 过时的问题
- Tomcat关闭后session的处理
- 如何处理过时的StringBufferInputStream
- 如何处理过时的StringBufferInputStream
- ImageRequest 过时的处理方式
- spring 3.2.2后 jdbcTemplate.queryForInt()方法过时的处理办法
- DefaultHttpClient过时想要继续使用的问题
- 【 HTTP 】---DefaultHttpClient is deprecated
- 接口调用,收到相应后的处理
- 用HTTP方式调用gearman任务处理
- 重载new和delete,处理内存溢出
- new失败后的三种处理方式
- New URI()可以自动处理Encode后的URL String
- HTTP 处理程序和 HTTP 模块概述
- 关于在使用表单提交时间到后台,提交的时间的类型的一些解决方法(主要针对oracle数据库)
- 第几天的问题
- C++两个链表的公共结点
- Unity3d开发 HTC vive手柄控制 手柄上各个按钮的点击事件
- Disgruntled Judge UVA
- new DefaultHttpClient过时处理建议和HTTP调用后关闭流处理
- Python3操作MySql数据库
- 【Codeforces B. Balanced Substring】
- C语言 乘法计算
- Hibernate-主键生成策略汇总
- <10/12>集训周记
- 算法
- select、poll、epoll之间的区别总结[整理]
- IT行业笔试题在线测试