因为工作中经常会写点接口类需求,写完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. JAVAEE学习——struts2_01:简介、搭建、架构、配置、action类详解和练习:客户列表

    一.struts2是什么 1.概念 2.struts2使用优势以及历史 二.搭建struts2框架 1.导包 (解压缩)struts2-blank.war就会看到 2.书写Action类 public ...

  2. abstract关键字

    概念 abstract关键字表示的是抽象的意思,可以用来修饰类和方法.修饰类我们称为抽象类,修饰方法我们称为抽象方法. abstract修饰类,抽象类 1.public  abstract  clas ...

  3. SQL构架(转)

    在一次的实际工作中碰到以下情况,在 SQL SERVER 2008中,新建了一个新用户去访问几张由其他用户创建的表,但是无法进行查询,提示“对象名'CustomEntry' 无效.”.当带上了架构名称 ...

  4. 信号处理——卷积(convolution)的实现

    作者:桂. 时间:2017-03-07  22:33:37 链接:http://www.cnblogs.com/xingshansi/p/6517301.html 前言 信号时域.频域对应关系,及其D ...

  5. MySql数据库基础操作——数据库、用户的创建,表的制作、修改等

    MySql 是一款使用便捷.轻量级的数据库.因为他体积小.速度快.安装使用简单.开源等优点,目前是使用最广泛的数据库.目前位于Oracle甲骨文公司旗下.那今天我们就来介绍一下数据库的基本操作.具体介 ...

  6. find的用法

    find在Linux系统中和其它工具,如sed.awk.grep等结合起来用,非常有用. 1.列出系统中所有属于root用户的“set uid”文件 #find / -perm 4755 –uid 0 ...

  7. 高性能队列Disruptor系列2--浅析Disruptor

    1. Disruptor简单介绍 Disruptor是一个由LMAX开源的Java并发框架.LMAX是一种新型零售金融交易平台,这个系统是建立在 JVM 平台上,核心是一个业务逻辑处理器,它能够在一个 ...

  8. php中引用&的一个小实例

    在百度知道上碰到一段关于php的引用符&的代码,对于初学都来说还是很考验理解分析能力的,把代码和自己的分析贴上来作一个备份,也与大家共勉. 代码片段: $arr =array(1,2,3,4) ...

  9. PHP二维数组合并,根据某个key合并

    /** *PHP二维数组合并,根据某个key合并 * @param type $v 要传入的组合阵列 * @param type $keyname 对应的KEY名称. * @param type $v ...

  10. win7休眠的开启与关闭方法

    从开始菜单中找到“附件→命令提示符”,右击选择“以管理员身份运行”,此时可能需要输入管理员密码或进行UAC确认,手工输入如下命令:powercfg -a,从这里可以清楚的看到,计算机是支持休眠的,只是 ...