1. HttpClient 概述
HttpClient 是 apache 组织下面的一个用于处理 HTTP 请求和响应的开源工具。它不是一个浏览器,也不处理客户端缓存等浏览器的功能。它只是一个类库!它在 JDK 的基本类库基础上做了更好的封装!
HttpClient 项目依赖于 HttpCore(处理核心的 HTTP 协议)、commons-codec(处理与编码有关的问题的项目)和 commons-logging(处理与日志记录有关问题的项目)。
如果你希望能够通过 HttpClient 向服务器上传文件等与 multipart 编码类型有关的请求,以及其它复杂的
MIME 类型,那么,你需要另外一个依赖包:HttpMime(它是专门处理与 MIME 类型有关问题的项目),
开始使用 HttpClient,我们加入了下列依赖包:
httpclient-4.0.1.jar
httpcore-4.0.1.jar
httpmime-4.0.1.jar
- 又依赖于 mime4j(apache-mime4j-0.6.jar)
commons-codec-1.4.jar
commons-logging-1.1.1.jar
commons-io-1.4.jar – 为了更方便处理与 IO 有关的需求
【如果你下载的是包含依赖包的压缩包,那么上述依赖包(除 commons-io-1.4.jar 外)都已经在其中
了!】
2. 了解 JDK 中有关 HTTP URL 处理的 API
因为 HttpClient 是对 JDK 中 java.net.*包下面的有关基础类库的封装,所以,我们有必要了解一下,这
些基础类库的简单用法和概念。
最简单的获取网页内容的示例
@Test public void testURLConnection() { try { String urlString = "http://16.10.113.8:8080/hiapi/paas/asset/db"; URL url = new URL(urlString); //代表了一个网址 URLConnection conn = url.openConnection(); InputStream is = conn.getInputStream(); //获得网页的内容 //将InputStream转换为Reader,并使用缓冲读取,提高效率,同时可以按行 BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8")); String line = null; while ((line = br.readLine()) != null) { System.out.println(line); } is.close(); } catch (Exception e) { e.printStackTrace(); } }
运行结果
[{"sign":"paas","deptId":103,"hostName":"66.3.125.80,66.3.125.81,66.3.125.82","port":"1521","dbId":88,"dbType":"ORACLE","dbName":"nnsptf","isCapture":null,"dbaUser":"system","dbaPwd":"oracle","dbAlias":"压测1"},{"sign":"paas","deptId":103,"hostName":"66.3.125.80,66.3.125.81,66.3.125.82","port":"1521","dbId":96,"dbType":"ORACLE","dbName":"cjecgc","isCapture":null,"dbaUser":"system","dbaPwd":"oracle","dbAlias":"测试ora"},{"sign":"paas","deptId":105,"hostName":"66.3.125.80,66.3.125.81,66.3.125.82","port":"1521","dbId":157,"dbType":"ORACLE","dbName":"uujarl","isCapture":null,"dbaUser":"system","dbaPwd":"oracle","dbAlias":"溧水库"},{"sign":"paas","deptId":105,"hostName":"66.3.125.80,66.3.125.81,66.3.125.82","port":"1521","dbId":164,"dbType":"ORACLE","dbName":"qwxutc","isCapture":null,"dbaUser":"system","dbaPwd":"oracle","dbAlias":"溧水数据库2"},{"sign":"paas","deptId":103,"hostName":"66.3.125.80,66.3.125.81,66.3.125.82","port":"1521","dbId":298,"dbType":"ORACLE","dbName":"vosrtz","isCapture":null,"dbaUser":"system","dbaPwd":"oracle","dbAlias":"zijin001"},{"sign":"paas","deptId":103,"hostName":"66.3.125.80,66.3.125.81,66.3.125.82","port":"1521","dbId":299,"dbType":"ORACLE","dbName":"pffklf","isCapture":null,"dbaUser":"system","dbaPwd":"oracle","dbAlias":"zijin002"}] Process finished with exit code 0
3.使用 HttpClient 获取网页内容
3.1 使用 GET 方式向后台递交请求
// org.apache.http.client.HttpClient @Test public void testHttpClient(){ try { //HttpClient主要负责执行请求 HttpClient httpclient = new DefaultHttpClient(); //利用HTTP GET向服务器发起请求 HttpGet get = new HttpGet("http://11.10.113.8:8080/hiapi/paas/asset/db"); //获得服务器响应的的所有信息 HttpResponse response = httpclient.execute(get); //获得服务器响应回来的消息体(不包括HTTP HEAD) HttpEntity entity = response.getEntity(); if(entity != null){ InputStream is = entity.getContent(); //将InputStream转换为Reader,并使用缓冲读取,提高效率,同时 BufferedReader br = new BufferedReader(new InputStreamReader(is,"UTF-8")); String line = null; while((line = br.readLine()) != null){ System.out.println(line); } is.close(); } //释放所有的链接资源,一般在所有的请求处理完成之后,才需要释放 httpclient.getConnectionManager().shutdown(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
3.2 自动获得响应的编码信息
我们希望程序能够自动分辨响应的内容的编码
@Test public void testHttpClient2() { try { //HttpClient主要负责执行请求 HttpClient httpclient = new DefaultHttpClient(); //利用HTTP GET向服务器发起请求 HttpGet get = new HttpGet("http://66.10.113.8:8080/hiapi/paas/asset/db"); //获得服务器响应的的所有信息 HttpResponse response = httpclient.execute(get); //获得服务器响应回来的消息体(不包括HTTP HEAD) HttpEntity entity = response.getEntity(); if (entity != null) { //获得响应的字符集编码信息 //即获取HTTP HEAD的:ContentType:text/html;charset=UTF-8中的字符集信息 String charset = EntityUtils.getContentCharSet(entity); System.out.println("响应的字符集是:" + charset); InputStream is = entity.getContent(); //使用响应中的编码来解释响应的内容 BufferedReader br = new BufferedReader(new InputStreamReader(is, charset)); String line = null; while ((line = br.readLine()) != null) { System.out.println(line); } is.close(); } //释放所有的链接资源,一般在所有的请求处理完成之后,才需要释放 httpclient.getConnectionManager().shutdown(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
3.3 设置代理服务器,访问网站
@Test public void testFetch03() { try { //HttpClient主要负责执行请求 HttpClient httpclient = new DefaultHttpClient(); //设置代理服务器 httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, new HttpHost("121.12.249.207", 3128)); //利用HTTP GET向服务器发起请求 HttpGet get = new HttpGet("http://www.baidu.com/");//new HttpGet("http://localhost:8080/cms"); //获得服务器响应的的所有信息 HttpResponse response = httpclient.execute(get); //获得服务器响应回来的消息体(不包括HTTP HEAD) HttpEntity entity = response.getEntity(); if (entity != null) { //获得响应的字符集编码信息 //即获取HTTP HEAD的:ContentType:text/html;charset=UTF-8中的字符集信息 String charset = EntityUtils.getContentCharSet(entity); System.out.println("响应的字符集是:" + charset); InputStream is = entity.getContent(); //使用响应中的编码来解释响应的内容 BufferedReader br = new BufferedReader(new InputStreamReader(is, charset)); String line = null; while ((line = br.readLine()) != null) { System.out.println(line); } is.close(); } //释放所有的链接资源,一般在所有的请求处理完成之后,才需要释放 httpclient.getConnectionManager().shutdown(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
3.4 获得重定向之后的网址信息
HttpClient 缺省情况下自动处理客户端重定向,即当你访问网页(比如 A 网页)之后,假设被重定向到了 B 网页,那么,HttpClient 将自动返回 B 网页的内容,无需再编程处理它!有时候我们可能想要知道 A 网 页被重定向到了哪里,也就是取得 B 网页的网址,那么可以通过下述例子获得:
@Test public void testFetch04(){ try { //HttpClient主要负责执行请求 HttpClient httpclient = new DefaultHttpClient(); HttpContext context = new BasicHttpContext(); //利用HTTP GET向服务器发起请求 HttpGet get = new HttpGet("http://localhost:8080/cms/backend/main.jsp"); //获得服务器响应的的所有信息 HttpResponse response = httpclient.execute(get,context); //获得重定向之后的主机地址信息 HttpHost targetHost = (HttpHost)context.getAttribute(ExecutionContext.HTTP_TARGET_HOST); System.out.println(targetHost); // http://localhost:8080 //获得实际的请求对象的URI(即重定向之后的"/cms/backend/login.jsp") HttpUriRequest actualRequest = (HttpUriRequest) context.getAttribute(ExecutionContext.HTTP_REQUEST); System.out.println(actualRequest.getURI()); //获得服务器响应回来的消息体(不包括HTTP HEAD) HttpEntity entity = response.getEntity(); if(entity != null){ //获得响应的字符集编码信息 //即获取HTTP HEAD的:ContentType:text/html;charset=UTF-8中的字符集信息 String charset = EntityUtils.getContentCharSet(entity); System.out.println("响应的字符集是:"+charset); InputStream is = entity.getContent(); //使用响应中的编码来解释响应的内容 BufferedReader br = new BufferedReader(new InputStreamReader(is,charset)); String line = null; while((line = br.readLine()) != null){ System.out.println(line); } is.close(); } //释放所有的链接资源,一般在所有的请求处理完成之后,才需要释放 httpclient.getConnectionManager().shutdown(); } catch (Exception e) { e.printStackTrace(); } }
3.5 自动 Cookie 处理
HttpClient 能够支持自动 Cookie 处理。设想一个典型的场景:首先打开登录页面,然后输入用户名和密 码登录,然后访问那些只有登录之后才能访问的网页…… 如果我们用浏览器,因为浏览器可以将登录之后的会话信息用 Cookie 存储在本地,所以,登录之后的每次 请求,都会自动向服务器发送 Cookie 的信息,我们利用 HttpClient,这些过程都全部可以自动化处理 了。
@Test public void testFetch05() { try { //HttpClient主要负责执行请求 HttpClient httpclient = new DefaultHttpClient(); HttpContext context = new BasicHttpContext(); //利用HTTP GET向服务器发起请求, HttpGet get = new HttpGet("http://localhost:8080/cms/backend/login.jsp"); //获得服务器响应的的所有信息 HttpResponse response = httpclient.execute(get, context); //获得服务器响应回来的消息体(不包括HTTP HEAD) HttpEntity entity = response.getEntity(); String charset = null; if (entity != null) { //获得响应的字符集编码信息 //即获取HTTP HEAD的:ContentType:text/html;charset=UTF-8中的字符集信息 charset = EntityUtils.getContentCharSet(entity); System.out.println("响应的字符集是:" + charset); InputStream is = entity.getContent(); //使用响应中的编码来解释响应的内容 BufferedReader br = new BufferedReader(new InputStreamReader(is, charset)); String line = null; while ((line = br.readLine()) != null) { System.out.println(line); } is.close(); } //************* 执行登录请求 ********************// HttpPost post = new HttpPost("http://localhost:8080/cms/backend/LoginServlet"); //添加POST参数 List<NameValuePair> nvps = new ArrayList<NameValuePair>(); nvps.add(new BasicNameValuePair("username", "admin")); nvps.add(new BasicNameValuePair("password", "admin")); post.setEntity(new UrlEncodedFormEntity(nvps, charset)); response = httpclient.execute(post); entity = response.getEntity(); if (entity != null) { InputStream is = entity.getContent(); //使用响应中的编码来解释响应的内容 BufferedReader br = new BufferedReader(new InputStreamReader(is, charset)); String line = null; while ((line = br.readLine()) != null) { System.out.println(line); } is.close(); } //******************* 请求文章查询 ********************// get = new HttpGet("http://localhost:8080/cms/backend/ArticleServlet"); response = httpclient.execute(get); entity = response.getEntity(); if (entity != null) { InputStream is = entity.getContent(); //使用响应中的编码来解释响应的内容 BufferedReader br = new BufferedReader(new InputStreamReader(is, charset)); String line = null; while ((line = br.readLine()) != null) { System.out.println(line); } is.close(); } //释放所有的链接资源,一般在所有的请求处理完成之后,才需要释放 httpclient.getConnectionManager().shutdown(); } catch (Exception e) { e.printStackTrace(); } }