一、httpclient引入话题
作为web开发,我们知道访问tomcat所部属的网站,很多情况下会使用浏览器进行访问web。但我们今天了解一下通过客户端的方式来访问web资源,get或者post的方式进行简单demo的演示。可能我们会问在什么情况下需要通过客户端编程的方式进行访问。那我这边先不阐述这是具体何用的。以后具体用到实际场景的时候才引入。
二、httpclient简单背景介绍
HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java net包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在很多的项目中,比如 Apache Jakarta 上很著名的另外两个开源项目 Cactus 和 HTMLUnit 都使用了 HttpClient。现在HttpClient最新版本为 HttpClient 4.1.
1) HttpClient 的范围
· 基于HttpCore的客户端HTTP运输实现库
· 基于经典(阻塞)I/O
· 内容无关
2) 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 可免费获取.
三、httpclient的客户端demo
1.下面是常用的httpclient访问web的get和post方式:
public class HttpClientTest {
private Logger logger=Logger.getLogger(this.getClass().getName());
/**
* get,不带参数
*/
@Test
public void getHttp(){
HttpClient http=new DefaultHttpClient();
HttpGet get=new HttpGet("http://localhost:8080/urlrewrite/");
try {
HttpResponse resp=http.execute(get);
HttpEntity entity=resp.getEntity();
logger.info("content Length:"+entity.getContentLength());
logger.info("content:"+EntityUtils.toString(entity));
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
//关闭连接,释放资源
http.getConnectionManager().shutdown();
}
}
/**
* post带参
*/
@Test
public void postHttp(){
HttpClient http=new DefaultHttpClient();
HttpPost post=new HttpPost("http://localhost:8080/httpserver/test");
List<NameValuePair> params=new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("username", "奥巴马"));
params.add(new BasicNameValuePair("password", "123456"));
try {
UrlEncodedFormEntity formEntity=new UrlEncodedFormEntity(params,"UTF-8");
post.setEntity(formEntity);
logger.info("uri:"+post.getURI());
try {
HttpResponse resp=http.execute(post);
HttpEntity entity=resp.getEntity();
logger.info("content length:"+entity.getContentLength());
logger.info("content:"+EntityUtils.toString(entity,"UTF-8"));
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}finally{
//关闭连接,释放资源
http.getConnectionManager().shutdown();
}
}
}
2.https的post访问
首先得开启tomcat的https访问
window运行cmd,keytool -genkey -alias tomcat -keyalg RSA -validity 60 -keystore D:\tomcat.keystore
cmd输出:
输入keystore密码:******
您的名字与姓氏是什么?
[Unknown]: localhost
您的组织单位名称是什么?
[Unknown]: it
您的组织名称是什么?
[Unknown]: dev
您所在的城市或区域名称是什么?
[Unknown]: bj
您所在的州或省份名称是什么?
[Unknown]: bj
该单位的两字母国家代码是什么
[Unknown]: CN
CN=localhost, OU= it, O= dev, L=bj, ST=bj, C=CN 正确吗?
[否]: Y
输入的主密码(如果和 keystore 密码相同,按回车):*******
参数说明:
-genkey表示生成密钥
-validity指定证书有效期,这里是60天
-alias指定别名,这里是tomcat
-keyalg指定算法,这里是RSA
-keystore指定存储位置,这里是D:\ tomcat.keystore
使用的自定义密码为 123456
Keytool 详细命令说明请参考百度百科;
*其中 您的名字与姓氏是什么? localhost是网站的域名或者ip,根据实际情况
ps:名字和姓氏必须填localhost或者127.0.0.1
<Connector
SSLEnabled="true"
URIEncoding="UTF-8"
clientAuth="false"
keystoreFile="conf/tomcat.keystore"
keystorePass="123456"
maxThreads="150"
port="8443"
protocol="HTTP/1.1"
scheme="https"
secure="true"
sslProtocol="TLS" />
2.通过浏览器对网站进行https访问
3.通过httpclient对网站进行https访问
/**
* https方式,带参
*/
@Test
public void getHttps(){
HttpClient hc=new DefaultHttpClient();
try {
KeyStore ks=KeyStore.getInstance(KeyStore.getDefaultType());
try {
FileInputStream fis=new FileInputStream(new File("d:\\tomcat.keystore"));
try {
ks.load(fis,"123456".toCharArray());
try {
SSLSocketFactory ssf=new SSLSocketFactory(ks);
Scheme sch=new Scheme("https", 8443, ssf);
hc.getConnectionManager().getSchemeRegistry().register(sch);
HttpPost post=new HttpPost("https://localhost:8443/httpserver/test");
List<NameValuePair> params=new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("username", "奥巴马"));
params.add(new BasicNameValuePair("password", "123456"));
UrlEncodedFormEntity formEntity=new UrlEncodedFormEntity(params,"UTF-8");
post.setEntity(formEntity);
HttpResponse resp=hc.execute(post);
HttpEntity entity=resp.getEntity();
logger.info("content length:"+entity.getContentLength());
logger.info("content:"+EntityUtils.toString(entity,"UTF-8"));
// HttpGet get=new HttpGet("https://localhost:8443/httpserver/test");
// HttpResponse resp=hc.execute(get);
// HttpEntity entity=resp.getEntity();
// logger.info("content length:"+entity.getContentLength());
// logger.info("content:"+EntityUtils.toString(entity,"UTF-8"));
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
}
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} catch (KeyStoreException e) {
e.printStackTrace();
}
}