因为工作中经常会写点接口类需求,写完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. abstract关键字

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

  2. node.js搭建代理服务器请求数据

    1.引入node.js中的模块 var http = require("http"); var url = require("url"); var qs = r ...

  3. 增强学习 | AlphaGo背后的秘密

    "敢于尝试,才有突破" 2017年5月27日,当今世界排名第一的中国棋手柯洁与AlphaGo 2.0的三局对战落败.该事件标志着最新的人工智能技术在围棋竞技领域超越了人类智能,借此 ...

  4. Linux系统vi模式下显示行号

    在命令模式下输入:set nu或者:set number都可以为vi设置行号,如果要取消的话,则输入:set nonu行号的设置是vi的环境设置,不会影响文本的内容.

  5. 门控开关项目--使用Multism仿真

    可以修改桥式整流电路的电容,发现容值不合适的时候,直流不平稳.

  6. 【巨杉答疑】巨杉数据库和mongodb有什么关系吗?

    哈罗,艾瑞巴蒂~巨杉答疑栏目今日上线啦! 巨杉数据库作为商业化开源软件,已经拥有大量社区用户.开源至今,大到分布式数据库原理.架构问题,小到SDB巨杉数据库的安装使用问题,大家似乎都有很多问题想要和我 ...

  7. linux vim编辑

    常用vim操作自我总结,大神请回避: vim 打开退出保存 打开:直接打开 vim practice_1.txt也可以先打开vim,后:e 文件路径 保存::w 文件名或者退出保存:wq! 普通模式下 ...

  8. java网络编程之socket(2)

    异步处理多客户端连接服务端 上篇讲到的是服务端接收一个客户端的请求之后就结束了,不能再接收其他客户端的请求了,实际情况上我们希望服务端能够处理来自不同用户的请求. 想到这里,或许我们可以用一个死循环, ...

  9. 记一次Nginx的配置

    记第一次Nginx的配置 Nginx 首先了解到Nginx是干什么的?它有哪些作用?比较常用到的基础功能有反向代理.负载均衡.正向代理.http服务器.这次部署用到的就是反向代理. 反向代理就是指在目 ...

  10. Flask+uwsgi+Nginx+Ubuntu部署

    学了一段时间flask,可是一直没有做过部署, 于是想着怎么部署呢, 想想,先吧服务给搞通吧,于是呢 就先想着去吧服务给搞起来,这里选择的是Flask+uwsgi+Nginx+Ubuntu, Pyth ...