转自:http://blog.csdn.net/xieyuooo/article/details/7182354

本文偏重使用,简单讲述httpclient,其实在网络编程中,基于java的实现几乎都是包装了socket的通信,然后来模拟各种各样的协议;httpclient其实就是模拟浏览器发起想服务器端的请求,而这种更加类似于JS的请求或页面的POST、GET,不过这种数据的返回一般需要得到有意义的数据,才方便做其他的交互,否则得到一个页面结果,全是标签了,毕竟不是浏览器,所以我们用httpclient更多使得系统的交互更加的简单,本文从如何使用httpclient开始说明到性能的优化方法切入:

1、httpclient客户端调用例子,以及服务器端需要做什么。

2、安全性怎么样去控制。

3、httpclient在并发量较高的调用下问题如何去解决。

1、httpclient客户端调用例子,以及服务器端需要做什么。

首先说明服务器端需要做什么,httpclient模拟的是一个浏览器,要服务器端进行数据交互,那么就是和浏览器一样发起请求,接受请求的操作,但是它和浏览器与服务器交互最大的区别是它没有登录动作,当然也可以通过模拟登录来完成cookie的获取,但是这个代码写起来就费劲了,而且这个账号必须在你的代码中写明登录账号才能获取到cookie,如果程序是单独自己用还是可以的,如果很多人用就有点乱了,因为每个人的密码你也得用某种方法传递到服务器端,但是没有cookie很明显会被服务器端拦截到某个直接的登录界面上去,从而得不到自己想要的数据,所以,我们先抛开安全性问题,那么就是将部分URL开放出来,也就是不经过过滤器的URL,或将某些目录单独开放出来访问,安全性的问题,第二章来讨论,OK,如果服务器端开放了一个URL路径后,客户端访问就像浏览器访问一个URL一样简单,用httpclient如何去访问呢?

在使用之前,需要先了解,httpclient是apache提供的,所以需要先引入相关的包,要使用它基本需要几个包:

commons-logging、commons-httpclient、commons-codec具体的版本以及引入方式请自己根据项目和工程打包方法决定,目前来讲maven引入是比较方便的方法,然后在代码前面引入:

[java] view plaincopy
  1. import org.apache.commons.httpclient.*;

<顺便说下 .* 这个说法,有人说用这个 * 是很慢的,对于现在的JVM来说只能说它是在乱说,一个一个引入唯一的好处是可以很快知道这个类是那个包下面来的,但是绝对不是提高性能,jvm在编译时早就决定了哪些是需要的,哪些是不需要的,如果引入同一个包太多,即使每个单独写,jvm也会给改成*,JVM的内存结构也不会因为某个类多引入几个*,就会修改他们之间的链接结构,初始化是由父子集成关系以及包装关系决定的,而运行是优化器决定的>

首先来看一个Get请求的非常简单的例子:

[java] view plaincopy
  1. try {
  2. HttpClient client = new HttpClient();//定义client对象
  3. client.getHttpConnectionManager().getParams().setConnectionTimeout(2000);//设置连接超时时间为2秒(连接初始化时间)
  4. GetMethod method = new GetMethod("http://www.google.com.hk/");//访问下谷歌的首页
  5. int statusCode = client.executeMethod(method);//状态,一般200为OK状态,其他情况会抛出如404,500,403等错误
  6. if (statusCode != HttpStatus.SC_OK) {
  7. System.out.println("远程访问失败。");
  8. }
  9. System.out.println(method.getResponseBodyAsString());//输出反馈结果
  10. client.getHttpConnectionManager().closeIdleConnections(1);
  11. }catch(....) {.....}

注意,上述反馈结果可能和你用一个socket去模拟一些系统没有什么区别,因为返回的内容没有任何价值,都是页面标签,当你和另一个系统交互时,它做response数据时,可以返回指定的json、xml等格式,用处就非常好用了,下面还会提及到它的好处;注意,采用GET方法,参数放在URL上面,要将非英文字符传递过去,需要对数据进行编码,如:

[java] view plaincopy
  1. String url = "http://www.xxx.xxx.com/xxx?name=" + URLEncoder.encode("谢宇" , "GBK") + "&otherName=" + URLEncoder.encode("谢宇" , "GBK") ;

其中URLEncoder使用apache或jdk自带的均可。

顺便再写个POST的例子:

[java] view plaincopy
  1. try {
  2. HttpClient client = new HttpClient();//定义client对象
  3. client.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "GBK");//指定传送字符集为GBK格式
  4. client.getHttpConnectionManager().getParams().setConnectionTimeout(2000);//设置连接超时时间为2秒(连接初始化时间)
  5. PostMethod method = new PostMethod("http://www.xxx.xxx.com/aaa/bbb.do");
  6. method.setRequestBody(new NameValuePair[] {
  7. new NameValuePair("name" , "谢宇"), new NameValuePair("otherName" , "谢宇")
  8. });
  9. int statusCode = client.executeMethod(method);
  10. if (statusCode != HttpStatus.SC_OK) {
  11. System.out.println("远程访问失败。");
  12. }
  13. System.out.println(method.getResponseBodyAsString());//输出反馈结果
  14. client.getHttpConnectionManager().closeIdleConnections(1);
  15. }catch(....) {.....}

可以看出,Post的例子和Get差不多,唯一的区别是传入参数的方法post采用了单独逐个写参数的方法,而get是在URL上面。

如果上面两个例子,在你的机器上跑通了,那么好,我们开始来讨论它的安全性问题:

2、安全性怎么样去控制

其实接口既然是人定义的,也就是协议是自己控制的,我们基于了一种轻量级的编程模式,让服务器端和客户端编码都变得十分简单,简单了,安全问题来了,谁都可以调用,如果你的接口是十分open的,那么这不是问题,只是控制好并发就可以,但是如果存在安全隐患的话,那么就有问题了,这个需要双方定义好一个加密方法,加密的粒度可以根据实际情况来决定,这种传送最好不要使用简单加密,一般有两种方法:

其一:使用不可逆加密算法(如:MD5,注意md5在对中文数据加密时,采用不同字符集转码加密出来结果也不一样),不可逆加密算法,就必须要双方都约定一个协议,在传递的参数上增加一个加密后的token值,其余的参数照样传递,加密过程为使用某种key与数据本身进行组合,并且存在一些动态变化性,将加密数据作为一个参数传递到接收方,接收方使用相同的方法得到一个密文,两个密文进行对比,若对比一致,则认证成功,若对比不一致,则认证失败;这样做算是比较简单的方法,有些还用了可逆和不可逆同时来用,先将数据按照可逆算法加密,然后再计算token,不过比较复杂些了。

其二:可逆加密算法,但是这种可逆,需要有一个密匙,最好的是非对称密匙,而且最好是双方的密匙可以随着某个值而变化,而不是固定的密匙。非对称密匙比较复杂,如果要用的话,这个可能会比较麻烦,安全级别极高的可以考虑,如果你的密匙本身可以随着某种方式得到一个变化,使用对称也基本够用,如:Blowfish就还算是不错的,但是没有密匙的就别用了,类似Base64就太简单了;当然你也可以像上面说的,可逆和不可逆混用来提高安全级别。

3、httpclient在并发量较高的调用下问题如何去解决

前面有提及到httpclient模拟系统之间的交互,如果系统之间的交互不高,是非常轻松的动作,不过httpclient是作为WEB容器的web请求存在,在http协议下,都是无状态的协议,也就是连接-请求-反馈-断开几个基本动作,好在现在WEB容器有了keep-alive的功能,包括很多负载均衡设备:如:LB、LVS、nginx、apache、jboss、tomcat等等都是支持的,虽然支持,但是看看上面的代码,就发现,每次请求都会重新建立连接,如何让他们不要重复创建连接呢?或者说在服务器端没有断开前不要重复创建连接,一个连接可以被使用多次请求,不至于一次请求就被断开一次;建立一次连接需要三次握手过程,以及更多的网络开销,所以你懂的。

道理很简单,其实和链接数据库差不多,将上面的请求的client对象以及method对象作为共享变量时,发起多次请求,平均效率会提升2倍左右,注意,这里是循环测试,而不是多线程。

但是对于并发较高的,我们不可能将method只用一个,因为它本身不能并发,于是我们就要用多个,在多个共享的对象中,如果控制好征用,有涉及到连接池的问题,不过这个连接池相对数据库的连接池要简单很多,因为,重试等动作,apache已经为你包装好了,你只需要顺序找和分配就可以了,如何降低竞争就是算法和策略的问题了。

但是,让客户端来编写这么一段代码是不是有点过分,当然你愿意写也是可以的,其实apache又为我们提供了一个后面就是异步httpclient(其实这里所知的异步并非真正的异步IO模式),也就是将这部分包装了,对于访问者来说还是同步的,只是在IO层面是非阻塞的了,这个就配合了服务器端的keep-alive,就像服务器端同时向一个站点请求多个资源时,我们希望是一个连接,而不是多个链接,其实在很多浏览器(如chrome、FF)都可以监控到它同时请求的服务器端资源,那么要用httpclient实现异步IO应该如何来做呢?其实也蛮简单的,下面是一个简单例子:

首先你要增加一个关于异步IO需要的包:

1、async-http-client包,可以在这里下载:https://oss.sonatype.org/content/repositories/releases/com/ning/async-http-client/1.6.2/

2、log4j的包,这个不用我说了,都知道在哪里

3、slf4j-spi 的包,目前用1.5以上的版本比较多。

4、slf4j-log4j 的包,可以看出,slf4j是在log4j基础上包装的。

OK,就这几个了,弄好后再看看下面这段代码,通过使用它,性能可以得到明显改善:

[java] view plaincopy
  1. AsyncHttpClient client = new AsyncHttpClient();
  2. try {
  3. Future<Response> f = client.prepareGet("http://www.google.com.hk/").execute();
  4. System.out.println(f.get().getResponseBody("Big5"));//谷歌的输出编码集为Big5,反向解析结果的时候使用
  5. }catch(...) {....}

这段代码是不是超级简单,可以通过上面描述的三种方式:

1、直接调用

2、将GetMethod或PostMethod对象作为共享对象反复使用。

3、使用AsyncHttpClient

这三种方法,非别使用一次调用、循环多次调用、并发调用来测试性能,后面两者的性能比第一种方法的性能要高很多。

转载于:https://www.cnblogs.com/chateldon/archive/2013/05/10/3070328.html

java之httpclient相关推荐

  1. java 微信群发多图文_[Java教程]httpClient实现微信公众号消息群发

    [Java教程]httpClient实现微信公众号消息群发 0 2016-09-21 20:00:10 1.实现功能 向关注了微信公众号的微信用户群发消息.(可以是所有的用户,也可以是提供了微信ope ...

  2. java接口自动化Excel占位符_基于maven+java+TestNG+httpclient+poi+jsonpath+ExtentReport的接口自动化测试框架...

    接口自动化框架 项目说明 本框架是一套基于maven+java+TestNG+httpclient+poi+jsonpath+ExtentReport而设计的数据驱动接口自动化测试框架,TestNG ...

  3. Java的HttpClient类以POST方式提交数据,目标端收到后中文乱码

     h ttpClient HttpMethod NameValuePair setRequestBody 今天开发时,遇到利用Java中HttpClient类以POST方式提交数据,目标收到后中文 ...

  4. java毕业设计——基于java+Jsoup+HttpClient的网络爬虫技术的网络新闻分析系统设计与实现(毕业论文+程序源码)——网络新闻分析系统

    基于java+Jsoup+HttpClient的网络爬虫技术的网络新闻分析系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于java+Jsoup+HttpClient的网络爬虫技术的网络 ...

  5. JAVA使用HttpClient调用webservice接口

    JAVA使用HttpClient调用webservice接口 关于HttpClient用法参考: HttpClient-4.5.2官方教程完整翻译 官方教程原文链接 HttpClient下载地址: 链 ...

  6. java的HttpClient如何去支持无证书访问https

    为什么80%的码农都做不了架构师?>>>    之前做调用华为认证接口时,没有证书,使用此方法,实测可用: 调用自定义类: if (url.startsWith("http ...

  7. 使用java的HttpClient实现抓取网页数据

    网络爬虫就是用程序帮助我们访问网络上的资源,我们一直以来都是使用HTTP协议来访问互联网上的网页,网络爬虫需要编写程序,在这里使用同样的HTTP协议来访问网页. 1.pom依赖 <depende ...

  8. java使用httpclient调用上传图片接口[示例]

    参考网站:nodejs使用http模块编写上传图片接口测试客户端 如果是java控制台app可以前往http://hc.apache.org/downloads.cgi下载新版httpclient库 ...

  9. JAVA——基于HttpClient的获取帆软FineReport报表爬虫DEMO

    HttpClient封装类:https://shentuzhigang.blog.csdn.net/article/details/104274609 FineReportUtil package c ...

  10. JAVA——基于HttpClient的通过单点登录方式(统一身份认证平台)登录正方教务系统[1999-2020]基本解决方案

    问题分析 通过HttpClient获取网页数据源,通过Jsoup解析数据.先模拟登录统一身份认证平台,再通过单点登录方式登录正方教务系统,最后获取相关信息.模拟浏览器正常操作,封装请求头信息获取SES ...

最新文章

  1. 转置卷积Transposed Convolution
  2. 关于linux内存管理
  3. Oracle ebs(E-Business Suite) 电子商务套件 简介
  4. python3.6安装教程-Python 3.6.6安装教程(附安装包) | 我爱分享网
  5. Tensorflow从入门到精通之——Tensorflow基本操作
  6. 诊断案例:从实例挂起到归档失败和内存管理的蝴蝶效应
  7. 回头看医疗行业信息化,怎一个乱字了得
  8. 9、10、11、12、13_添加标注 (Annotations)、添加网格线(Grid Lines)、显示中文字体、保存图形(saving Figures)、高质量矢量图输出
  9. mysql数据库五大对象_数据库的三大范式以及五大约束
  10. Ubuntu彻底删除MySQL重装MySQL
  11. pthread_create函数阻塞了主线程_5个状态,Python 中线程的生命周期
  12. Java 8 新日期时间 API ( 上 ) – 本地日期时间
  13. sonarqube + nexus 分析项目组成员代码状况,并生成报表
  14. 操作系统之进程通信:高级通信机制四大类
  15. 最好用的jpg转pdf软件
  16. 华中师范大学计算机学院学分绩,华中师范大学学生学业成绩表(模板)
  17. FBW7通过端粒脱帽介导肺纤维化和衰老
  18. 快速计算delay函数中for循环延时程序占用的时间
  19. Multisim高频电子线路2.7章LC谐振电路的仿真
  20. Redis 进阶篇:发布订阅模式原理与运用

热门文章

  1. 一帧1920*1080的画面有多少比特,需要多大带宽观看是才不会卡顿?
  2. eact-native-linear-gradient
  3. 安卓开发颜色以及对应代码(转载)
  4. 吊打何同学?B 站 UP 主 24 小时肝出 AirDesk 平替,成本 6000!
  5. 【已解决】maven打包时xxx.xxx程序包不存在
  6. 博士申请 | 香港大学黄凯斌教授招收6G通信与机器学习方向全奖博士生
  7. 春天里,程序猿宅男的“桃花”怎么开
  8. Bundle Adjustment简述
  9. 用友T+改成IIS-网站报500.19错误代码0x8007000d问题解决
  10. seo网站关键词优化三大要素:技术 思路 执行力