因为工作中经常会写点接口类需求,写完HTTP的接口后,就要写测试类来调下服务端的代码。
最近写新的测试调用代码时候,发现项目中new DefaultHttpClient()实例过期很久了,于是查阅了些资料用新版本代码替换了手上项目的代码并且正常测试完、生产上也正常运行完,算是一次补习,特记录下替换过程和调用完后的处理。

1:来看下原来的调用代码,也是最常用的(httpclient版本超过4.2.6):

  项目原先用的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中处理。

  

  看AbstractHttpClient 继承了CloseableHttpClient的CloseableHttpClient:

  @ThreadSafe //线程安全
  public abstract class CloseableHttpClient implements HttpClient, Closeable

  不难看出实现了httpclient,那么调用方法有了,还实现了关闭流,说明调用完毕后会做关闭处理。CloseableHttpResponse也替换了原来的HttpResponse ,结合资料写下新的调用类:

        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:总结:

  经过几天下来的学习,要知道调用http后,不能只是把client动作关闭就可以的,还需要把response返回参数接收处理完毕后关闭掉。

  因为每次调用的不同,不及时关闭在大请求量下就需要谨慎设计代码的安全性了。

new DefaultHttpClient过时处理建议和HTTP调用后关闭流处理的更多相关文章

  1. c/c++ socket API 调用后的错误判断 perror errno

    socket API 调用后的错误判断 perror errno 调用完socket API后,需要判断调用是否成功与失败.如果失败,会自动设置errno(是个整数), 并且用perror可以打印出具 ...

  2. 用eclipse 检索SVN 上 myEclipse 建的web项后,成java项目解决方法

    用eclipse 检索SVN 上 myEclipse 建的web项后,成java项目解决方法 在网上找了非常多,都无论用. 说添加.project 文件几个属性.但我发现里面都有,在我这里无论什么用. ...

  3. 文件件监听器,android系统拍照功能调用后删除系统生成的照片

    先说说要实现的功能: android调用系统拍照功能实时 预览 删除 上传 保存 (用户不能再本地文件夹中看到拍的照片) 再说说遇到的问题: 1.调用系统拍照在系统自带的拍照文件夹中生成一张随机命名图 ...

  4. ORACLE 数据库建了非法表后无法操作和删除问题

    问题描述: oracle 用PL/SQL DEVELOPER 可视化建表时,表名没有按照规范,建立一个非法格式的表 ICD-10th-Version (中间有横杆,非法).但是不知道怎么回事却建成功了 ...

  5. append、appendTo、prepend、prependTo、before、insertBefore、after、insertAfter、replaceAll方法被调用后,原本在页面上显示的元素会消失

    详细描述: $ele.append..appendTo..prepend..prependTo..before..insertBefore..after..insertAfter..replaceAl ...

  6. malloc调用后经历了什么?

    进程生成虚拟地址空间,有堆地址,由于是虚拟地址,所以没有做内存碎片化处理,只是在虚拟内存不够的时候调用brk,进行堆大小的调整,然后申请到虚拟内存是页,同MMU映射到物理地址,然后并不是每个页都预先加 ...

  7. [ios]IOS的AppDelegate方法中的事件触发调用 以及 关闭 ios应用程序

    IOS的AppDelegate方法中的事件触发调用 参考:http://blog.sina.com.cn/s/blog_a573f7990101bphp.html //当应用程序将要进入非活动状态执行 ...

  8. Project Server调用PSI关闭任务以进行更新锁定任务

    /// <summary> /// 锁定和解锁项目任务 /// </summary> /// <param name="projectuid"> ...

  9. 问题-[Delphi]SendMessageTimeout调用后卡住点击任务栏还会出现窗体处理

    问题现象:在使用SendMessageTimeout函数后,5秒后WIN把进程挂在起.这时把程序最小化(原因就是不想让用户看到卡的界面),但点击任务栏按钮界面还原了,拦截消息失败(原因是挂起后消息都放 ...

随机推荐

  1. final关键字(最终的)

    1.fianl关键字可以用来修饰类.属性.方法: 2.final关键字修饰的类不能再继承: 如:String   String类是final修饰的类不能被继承 3.final关键字修饰的方法不能被重写 ...

  2. bettercap实现内网Dns欺骗

    目的 让内网的所有计算机浏览网页的时候, 出现我的钓鱼页面 准备 kali系统 Bettercap dns文件 通过ifconfig查看当前计算机的ip, 我这边为, 192.168.1.150 创建 ...

  3. Solr集群搭建

    SolrCloud需要solr基于zookeeper部署,zookeeper是一个集群管理软件,由于SolrCloud需要由多台服务器组成.由zookeeper来进行协调管理.Zookeeper是一个 ...

  4. LoadRunner11_录制Oracle数据库脚本

    [oracle环境] ①oracle:无需在本地安装oracle,但是oracle的odbc驱动一定要装:(我的安装路径为 D:\oracle ).安装好后在环境变量 " Path &quo ...

  5. GitHub:多人协作下的分支处理

    GitHub上的团队协作 远程信息 git remote:查看远程库的信息 git remote -v:查看远程库的详细信息 推送分支 git push origin 要推送的分支:比如git pus ...

  6. SICP-1.7-递归函数

    递归函数 函数内部直接或间接的调用函数自身 将复杂问题简单化 例子程序 def sum_digits(n): """Return the sum of the digit ...

  7. Advice详解

    1.前置增强 BeforeAdvice是前置增强的接口,方法前置增强的MethodBeforeAdvice接口是其子类, MethodBeforeAdvice接口仅仅定义了唯一的方法:before(M ...

  8. windows安装nvm管理node版本

    1.卸载原本系统里面的nodejs 2.下载nvm安装包:https://github.com/coreybutler/nvm-windows/releases ---->nvm-setup.z ...

  9. php数组根据某键值,把相同键值的合并最终生成一个新的二维数组

    <?php $a=array( '0'=>array( 'id'=>'1', 'names'=>'jack', '0'=>'sendone' ), '1'=>arr ...

  10. Array和ArrayList的区别与联系

    博主今天去了一个java的实习面试,发现有好多java最基础的数据结构对于博主来说反而感到陌生,在面试官问一些常见的例如HashMap这样的数据结构,博主能回答的头头是道,但是在问到Array和Arr ...