HttpClient4.0学习
2013-10-09 14:16
405 查看
1、初始化HttpParams,设置组件参数
//HttpParams接口代表一个不可改变值的集合,定义一个组件运行时行为。代表一个对象集合,该集合是一个键到值的映射。
//HttpParams作用是定义其他组件的行为,一般每个复杂的组件都有它自己的HttpParams对象。
HttpParams
params = new BasicHttpParams();
//
HTTP 协议的版本,1.1/1.0/0.9
HttpProtocolParams.setVersion(params,
HttpVersion.HTTP_1_1);
HttpProtocolParams.setUserAgent(params,
"HttpComponents/1.1");
HttpProtocolParams.setUseExpectContinue(params,
true);
ConnManagerParams.setMaxTotalConnections(params,
maxconnections); // 设置最大连接数maxconnections);
ConnManagerParams.setTimeout(params,
timeout*1000); // 设置超时时间 timeout 秒
2、初始化SchemeRegistry,设置访问协议
//Scheme类表示一个协议方案,例如"http"或者"https"和包含许多的协议属性,
//例如缺省的端口和socket工厂常用于为指定的协议创建java.net.Socket实例,SchemeRegistry类被用来维护一个Schemes的集合
SchemeRegistry
schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new
Scheme("http", PlainSocketFactory
.getSocketFactory(), 80));
schemeRegistry.register(new
Scheme("https", SSLSocketFactory
.getSocketFactory(), 443));
3、初始化httpclient会话连接管理器
//HTTP连接是复杂、有状态的,非线程安全的对象需要适当的管理正确的功能。HTTP连接每次仅被一个执行的线程使用,
//HttpClient利用一个特殊的实体管理访问HTTP连接,称为HTTP连接管理器,由ClientConnectionManager接口表示。
//HTTP连接管理器的充当一个新的HTTP连接工厂,管理持续的连接和同步的访问持续的连接,确保每次只有一个线程能访问连接。
ClientConnectionManager
connectionManager = new ThreadSafeClientConnManager(params,
schemeRegistry);
4、初始化httpClient并加入会话连接管理器,此步很重要,对于使用httpclient多线程并发访问服务系统很有用
//HttpClient最重要的功能是执行HTTP方法。执行一个HTTP方法涉及一个或多个HTTP请求/
HTTP响应信息交流,
//通常是由HttpClient内部处理。用户提供一个请求对象,HttpClient发送请求到目标服务器,
//希望服务器返回一个相应的响应对象,或者抛出一个异常(如果执行失败)。
HttpClient
httpClient = new DefaultHttpClient(connectionManager, params);
5、定义HttpHost
//
HttpHost代表访问的主机
String
sHost = "www.hao123.com"; //访问服务器的主网址
httpHost
= new HttpHost(sHost);
6、执行get请求
6.1 先定义方法getResponseContent,用来根据指定系统编码获取响应主体内容,很有用的方法
public
String getResponseContent(HttpEntity responseEntity)
throws Exception {
byte[] bytes = EntityUtils.toByteArray(responseEntity);
String
sCharSet="GB2312"; //这里可以定义你指定的编码,中文网站编码一般为GB2312
return new String(bytes, sCharSet);
}
6.2 执行get请求,获取响应的html内容
String
sURL="/abc/index.html"; //定义你需要访问的网址后面的路径
HttpGet
httpGet = new HttpGet(sURL);//定义get请求
HttpResponse
httpResponse = httpClient.execute(httpHost, httpGet); //使用httpclient执行get请求并返回响应 访问的网址为
www.hao123.com/abc/index.html
//
2 获取响应
HttpEntity responseEntity = httpResponse.getEntity();
String sReturnHtml = getResponseContent(responseEntity);//得到get请求返回的html页面,然后就做你想做的东西了
//比如解析html页面,得到你想得到的东西
httpGet.abort();//释放连接资源,很重要,不能缺少
7、执行post请求
7.1初始化httppost
String
sURL="/abc/index.html";
HttpPost
httpPost = new HttpPost(sURL);
7.2设置Post请求参数NameValuePair
List<NameValuePair>
nvps = new ArrayList<NameValuePair>();
nvps.add(new
BasicNameValuePair("name", "testname"));
nvps.add(new
BasicNameValuePair("password", "testpassword"));
7.3把请求参数按指定编码设置到httppost中,设置httppost请求头内容,可解决中文乱码问题,非常重要
String
sCharSet="GB2312";
httpPost.setEntity(new
UrlEncodedFormEntity(nvps, sCharSet));
//
---begin解决中文乱码问题
httpPost.addHeader("Content-Type","application/x-www-form-urlencoded");
httpPost.addHeader("Accept-Language",
"zh-cn");
httpPost.addHeader("Accept-Encoding",
"gzip, deflate");
//
---end
7.4执行post请求,得到响应做其他操作
HttpResponse
httpResponse = httpClient.execute(httpHost, httpPost);
HttpEntity
responseEntity = httpResponse.getEntity();
String
sHtml = getResponseContent(responseEntity);
httpPost.abort();//释放连接资源
8
connectionManager.shutdown();//关闭连接管理器
总结:使用httpclient访问需要用户登录的网站做相关操作,需要从登录、判断登录成功、做你想要的事情、退出 一连贯动作
因为大部分网站服务器是根据用户访问的会话session来判断一个用户是否在线的才能做相关操作,所以退出动作不实现的话,
在httpclient多线程并发访问网站的时候,服务器会出现数据混乱等想不到的状况。
判断登录是否成功这个问题,我的解决方案是获取登录POST请求返回响应,然后从响应中获取重定向地址。
一般的WEB服务系统设计时,登录成功和失败返回的重定向地址是不一致的。所以我只要判断返回的重定向地址是否是成功的就可以了。
public String getRedirectLocation(HttpResponse response) {
String sReturn;
Header locationHeader = response.getFirstHeader("Location");
if (locationHeader == null) {
sReturn = "";
} else {
sReturn = locationHeader.getValue();
}
if (log.isDebugEnabled()) {
log.debug("##########重定向URL:" + sReturn);
}
return sReturn;
}
POST请求中文乱码问题在网上搜索了很多方案,都无法解决,
后来我用HttpAnalyzer分析用浏览器访问正常情况时,发现请求头中包含了三个参数
"Content-Type"、"Accept-Language"、
"Accept-Encoding",在httppost中添加请求头加入这几个参数后,发现问题解决了。
因为和4.0之前的版本比较,发生了很多变化,所以上面的总结对之前的版本不实用。
需要的jar包:
apache-mime4j-0.6.jar
commons-codec-1.3.jar
commons-logging-1.1.1.jar
httpclient-4.0.3.jar
httpcore-4.0.1.jar
httpmime-4.0.3.jar
//HttpParams接口代表一个不可改变值的集合,定义一个组件运行时行为。代表一个对象集合,该集合是一个键到值的映射。
//HttpParams作用是定义其他组件的行为,一般每个复杂的组件都有它自己的HttpParams对象。
HttpParams
params = new BasicHttpParams();
//
HTTP 协议的版本,1.1/1.0/0.9
HttpProtocolParams.setVersion(params,
HttpVersion.HTTP_1_1);
HttpProtocolParams.setUserAgent(params,
"HttpComponents/1.1");
HttpProtocolParams.setUseExpectContinue(params,
true);
ConnManagerParams.setMaxTotalConnections(params,
maxconnections); // 设置最大连接数maxconnections);
ConnManagerParams.setTimeout(params,
timeout*1000); // 设置超时时间 timeout 秒
2、初始化SchemeRegistry,设置访问协议
//Scheme类表示一个协议方案,例如"http"或者"https"和包含许多的协议属性,
//例如缺省的端口和socket工厂常用于为指定的协议创建java.net.Socket实例,SchemeRegistry类被用来维护一个Schemes的集合
SchemeRegistry
schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new
Scheme("http", PlainSocketFactory
.getSocketFactory(), 80));
schemeRegistry.register(new
Scheme("https", SSLSocketFactory
.getSocketFactory(), 443));
3、初始化httpclient会话连接管理器
//HTTP连接是复杂、有状态的,非线程安全的对象需要适当的管理正确的功能。HTTP连接每次仅被一个执行的线程使用,
//HttpClient利用一个特殊的实体管理访问HTTP连接,称为HTTP连接管理器,由ClientConnectionManager接口表示。
//HTTP连接管理器的充当一个新的HTTP连接工厂,管理持续的连接和同步的访问持续的连接,确保每次只有一个线程能访问连接。
ClientConnectionManager
connectionManager = new ThreadSafeClientConnManager(params,
schemeRegistry);
4、初始化httpClient并加入会话连接管理器,此步很重要,对于使用httpclient多线程并发访问服务系统很有用
//HttpClient最重要的功能是执行HTTP方法。执行一个HTTP方法涉及一个或多个HTTP请求/
HTTP响应信息交流,
//通常是由HttpClient内部处理。用户提供一个请求对象,HttpClient发送请求到目标服务器,
//希望服务器返回一个相应的响应对象,或者抛出一个异常(如果执行失败)。
HttpClient
httpClient = new DefaultHttpClient(connectionManager, params);
5、定义HttpHost
//
HttpHost代表访问的主机
String
sHost = "www.hao123.com"; //访问服务器的主网址
httpHost
= new HttpHost(sHost);
6、执行get请求
6.1 先定义方法getResponseContent,用来根据指定系统编码获取响应主体内容,很有用的方法
public
String getResponseContent(HttpEntity responseEntity)
throws Exception {
byte[] bytes = EntityUtils.toByteArray(responseEntity);
String
sCharSet="GB2312"; //这里可以定义你指定的编码,中文网站编码一般为GB2312
return new String(bytes, sCharSet);
}
6.2 执行get请求,获取响应的html内容
String
sURL="/abc/index.html"; //定义你需要访问的网址后面的路径
HttpGet
httpGet = new HttpGet(sURL);//定义get请求
HttpResponse
httpResponse = httpClient.execute(httpHost, httpGet); //使用httpclient执行get请求并返回响应 访问的网址为
www.hao123.com/abc/index.html
//
2 获取响应
HttpEntity responseEntity = httpResponse.getEntity();
String sReturnHtml = getResponseContent(responseEntity);//得到get请求返回的html页面,然后就做你想做的东西了
//比如解析html页面,得到你想得到的东西
httpGet.abort();//释放连接资源,很重要,不能缺少
7、执行post请求
7.1初始化httppost
String
sURL="/abc/index.html";
HttpPost
httpPost = new HttpPost(sURL);
7.2设置Post请求参数NameValuePair
List<NameValuePair>
nvps = new ArrayList<NameValuePair>();
nvps.add(new
BasicNameValuePair("name", "testname"));
nvps.add(new
BasicNameValuePair("password", "testpassword"));
7.3把请求参数按指定编码设置到httppost中,设置httppost请求头内容,可解决中文乱码问题,非常重要
String
sCharSet="GB2312";
httpPost.setEntity(new
UrlEncodedFormEntity(nvps, sCharSet));
//
---begin解决中文乱码问题
httpPost.addHeader("Content-Type","application/x-www-form-urlencoded");
httpPost.addHeader("Accept-Language",
"zh-cn");
httpPost.addHeader("Accept-Encoding",
"gzip, deflate");
//
---end
7.4执行post请求,得到响应做其他操作
HttpResponse
httpResponse = httpClient.execute(httpHost, httpPost);
HttpEntity
responseEntity = httpResponse.getEntity();
String
sHtml = getResponseContent(responseEntity);
httpPost.abort();//释放连接资源
8
connectionManager.shutdown();//关闭连接管理器
总结:使用httpclient访问需要用户登录的网站做相关操作,需要从登录、判断登录成功、做你想要的事情、退出 一连贯动作
因为大部分网站服务器是根据用户访问的会话session来判断一个用户是否在线的才能做相关操作,所以退出动作不实现的话,
在httpclient多线程并发访问网站的时候,服务器会出现数据混乱等想不到的状况。
判断登录是否成功这个问题,我的解决方案是获取登录POST请求返回响应,然后从响应中获取重定向地址。
一般的WEB服务系统设计时,登录成功和失败返回的重定向地址是不一致的。所以我只要判断返回的重定向地址是否是成功的就可以了。
public String getRedirectLocation(HttpResponse response) {
String sReturn;
Header locationHeader = response.getFirstHeader("Location");
if (locationHeader == null) {
sReturn = "";
} else {
sReturn = locationHeader.getValue();
}
if (log.isDebugEnabled()) {
log.debug("##########重定向URL:" + sReturn);
}
return sReturn;
}
POST请求中文乱码问题在网上搜索了很多方案,都无法解决,
后来我用HttpAnalyzer分析用浏览器访问正常情况时,发现请求头中包含了三个参数
"Content-Type"、"Accept-Language"、
"Accept-Encoding",在httppost中添加请求头加入这几个参数后,发现问题解决了。
因为和4.0之前的版本比较,发生了很多变化,所以上面的总结对之前的版本不实用。
需要的jar包:
apache-mime4j-0.6.jar
commons-codec-1.3.jar
commons-logging-1.1.1.jar
httpclient-4.0.3.jar
httpcore-4.0.1.jar
httpmime-4.0.3.jar
相关文章推荐
- 淘宝开源网络框架TBNET分析
- 虚拟机网络连接方式和网络设置
- Cisco网络设备安全管理和报告
- iOS ASIHTTPRequest详解
- boost 网络库 之异步
- Http协议学习笔记一
- boost 网络库使用 之同步
- 最开始下载的内核源码和机子的kernel不匹配,参照http://blog.csdn.net/hecant/archive/2007/10/31/1859606.aspx:
- HTTP 错误 500.21 - Internal Server Error 处理程序“ExtensionlessUrlHandler-ISAPI-4.0_64bit”在其模块列表中有一个错误模块“IsapiModule” 解决方法
- tcpdump工具
- HTTP 协议详解
- 网络子系统44_ip协议源路由选项处理
- 使用钩子参与到TCP拥塞事件的处理中
- 使用钩子参与到TCP拥塞事件的处理中
- LwIP 协议栈源码详解 ——TCP/IP 协议的实现(五:pbuf 释放)
- HttpModule与HttpHandler详解
- Switch to HTTPS Now, For Free
- YUM源之常见问题
- Java TCP/UDP socket 编程流程总结
- LwIP 协议栈源码详解 ——TCP/IP 协议的实现(四:数据包 pbuf )