HttpClient4.1 使用示例
一、HttpClient简介
HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在很多的项目中,比如 Apache Jakarta 上很著名的另外两个开源项目 Cactus 和 HTMLUnit 都使用了 HttpClient。现在HttpClient最新版本为 HttpClient 4.3.
二、HttpClient特性
- 基于标准,纯净的java语言.实现了Http1.0和Http1.1
- 以可扩展的面向对象的结构实现了Http全部的方法 (GET, POST, PUT, DELETE, HEAD, OPTIONS, and TRACE).
- 支持HTTPS协议.
- 通过Http代理建立透明的连接.
- 利用CONNECT 方法通过Http代理建立隧道的https连接.
- Basic, Digest, NTLMv1, NTLMv2, NTLM2 Session, SNPNEGO/Kerberos 认证方案.
- 插件式的自定义认证方案.
- 便携可靠的套接字工厂使它更容易的使用第三方解决方案.
- 连接管理器支持多线程应用.支持设置最大连接数,同时支持设置每个主机的最大连接数.发现并关闭过期的连接.
- Automatic Cookie handling for reading Set-Cookie: headers from the server and sending them back out in a Cookie: header when appropriate.
- 插件式的自定义Cookie策略.
- Request output streams to avoid buffering any content body by streaming directly to the socket to the server.
- Response input streams to efficiently read the response body by streaming directly from the socket to the server.
- 在http1.0和http1.1中利用KeepAlive保持持久连接.
- 直接获取服务器发送的response code和 headers.
- 设置连接超时的能力.
- 实验性的支持http1.1 response caching.
- 源代码基于Apache License 可免费获取.
下载地址: http://hc.apache.org/downloads.cgi
三、详细讲解
这里为了更好的理解,新建了一个java se的工程,如下图所示
HttpClientTest类
package com.yulore.httpproxy; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.util.ArrayList; import java.util.List; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.ParseException; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import org.junit.Test; public class HttpClientTest { @Test public void jUnitTest(){ get(); } /** * HttpClient连接SSL */ private void ssl() { DefaultHttpClient httpclient = new DefaultHttpClient(); try { KeyStore trustStore = KeyStore.getInstance(KeyStore .getDefaultType()); FileInputStream instream = new FileInputStream(new File( "d:\\tomcat.keystore")); try { // 加载keyStore d:\\tomcat.keystore trustStore.load(instream, "123456".toCharArray()); } catch (CertificateException e) { e.printStackTrace(); } finally { try { instream.close(); } catch (Exception ignore) { } } // 穿件Socket工厂,将trustStore注入 SSLSocketFactory socketFactory = new SSLSocketFactory(trustStore); // 创建Scheme Scheme sch = new Scheme("https", 8443, socketFactory); // 注册Scheme httpclient.getConnectionManager().getSchemeRegistry().register(sch); // 创建http请求(get方式) HttpGet httpget = new HttpGet( "https://localhost:8443/myDemo/Ajax/serivceJ.action"); System.out.println("executing request" + httpget.getRequestLine()); HttpResponse response = httpclient.execute(httpget); HttpEntity entity = response.getEntity(); System.out.println("----------------------------------------"); System.out.println(response.getStatusLine()); if (entity != null) { System.out.println("Response content length: " + entity.getContentLength()); String ss = EntityUtils.toString(entity); System.out.println(ss); EntityUtils.consume(entity); } } catch (ParseException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (KeyManagementException e) { e.printStackTrace(); } catch (UnrecoverableKeyException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (KeyStoreException e) { e.printStackTrace(); } finally { httpclient.getConnectionManager().shutdown(); } } /** * post方式提交表单(模拟用户登录请求) */ private void postForm() { // 创建默认的httpClient实例. HttpClient httpclient = new DefaultHttpClient(); // 创建httppost HttpPost httppost = new HttpPost( "http://localhost:8080/myDemo/Ajax/serivceJ.action"); // 创建参数队列 List<NameValuePair> formparams = new ArrayList<NameValuePair>(); formparams.add(new BasicNameValuePair("username", "admin")); formparams.add(new BasicNameValuePair("password", "123456")); UrlEncodedFormEntity uefEntity; try { uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8"); httppost.setEntity(uefEntity); System.out.println("executing request " + httppost.getURI()); HttpResponse response; response = httpclient.execute(httppost); HttpEntity entity = response.getEntity(); if (entity != null) { System.out.println("--------------------------------------"); System.out.println("Response content: " + EntityUtils.toString(entity, "UTF-8")); System.out.println("--------------------------------------"); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 关闭连接,释放资源 httpclient.getConnectionManager().shutdown(); } } /** * 发送 post请求访问本地应用并根据传递参数不同返回不同结果 */ private void post() { // 创建默认的httpClient实例. HttpClient httpclient = new DefaultHttpClient(); // 创建httppost HttpPost httppost = new HttpPost( "http://localhost:8080/myDemo/Ajax/serivceJ.action"); // 创建参数队列 List<NameValuePair> formparams = new ArrayList<NameValuePair>(); formparams.add(new BasicNameValuePair("type", "house")); UrlEncodedFormEntity uefEntity; try { uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8"); httppost.setEntity(uefEntity); System.out.println("executing request " + httppost.getURI()); HttpResponse response; response = httpclient.execute(httppost); HttpEntity entity = response.getEntity(); if (entity != null) { System.out.println("--------------------------------------"); System.out.println("Response content: " + EntityUtils.toString(entity, "UTF-8")); System.out.println("--------------------------------------"); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 关闭连接,释放资源 httpclient.getConnectionManager().shutdown(); } } /** * 发送 get请求 */ private void get() { HttpClient httpclient = new DefaultHttpClient(); try { // 创建httpget. HttpGet httpget = new HttpGet("http://www.baidu.com/"); System.out.println("executing request " + httpget.getURI()); // 执行get请求. HttpResponse response = httpclient.execute(httpget); // 获取响应实体 HttpEntity entity = response.getEntity(); System.out.println("--------------------------------------"); // 打印响应状态 System.out.println(response.getStatusLine()); if (entity != null) { // 打印响应内容长度 System.out.println("Response content length: " + entity.getContentLength()); // 打印响应内容 System.out.println("Response content: " + EntityUtils.toString(entity)); } System.out.println("------------------------------------"); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (ParseException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 关闭连接,释放资源 httpclient.getConnectionManager().shutdown(); } } }
详细信息请看程序中的注释
注意事项
JUnit运行测试时报错,错误日志信息如下:
java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
at org.apache.http.impl.client.AbstractHttpClient.<init>(AbstractHttpClient.java:182)
at org.apache.http.impl.client.DefaultHttpClient.<init>(DefaultHttpClient.java:150)
at com.yulore.httpproxy.HttpClientTest.get(HttpClientTest.java:180)
at com.yulore.httpproxy.HttpClientTest.jUnitTest(HttpClientTest.java:36)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
... 27 more
缺少commons-logging jar包,导入commons-logging.jar即可
commons-logging.jar 下载地址