`
xcy13638760
  • 浏览: 51535 次
社区版块
存档分类
最新评论

HttpClient 操作工具类

 
阅读更多

注:http://my.oschina.net/xiahuawuyu/blog/82580 为此篇文章的链接。

设置post方法的header,增加红色字体部分的配置:

HttpClient client = new HttpClient();
client.getParams().setBooleanParameter(
"http.protocol.expect-continue", false);

PostMethod method = new PostMethod(url);

method.addRequestHeader("Connection", "close");

一。 http 工作 大至 原理

HTTP工作原理
1.客户端和服务器。
2.建立连接,客户端向服务器发送一个请求。
3.服务器接受到请求后,向客户端发出响应信息。
4.客户端与服务器断开链接。


请求报文与响应报文。
请求报文格式:
请求行-->通用信息头-->请求头-->实体头-->报文主体
响应报文格式:
状态行-->通用信息头-->相应头-->实体头-->报文主体

android 集成了org.apache.http.client.HttpClient; 可以直接实现简单的htttp Get 和 Post 操作 但是不支持 多部post 操作 。 要实现 多部分post 操作还需要导 额外 jar包 这里就不介绍了。

实现一个 http 操作

1 。需要生成一个Http Client 客户端对象 。

2。 生成响应的请求对象 。

3。接受发回的信息 。

4.。解析返回的信息。

直接看 get 请求操作 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
publicString httpGet(String url, String params) throwsException{
String result="";//返回信息
if(null!=params&&!params.equals(""))
{
url += "?"+ params;
}
//创建一个httpGet请求
HttpGet request=newHttpGet(url);
//创建一个htt客户端
HttpClient httpClient=newDefaultHttpClient();
//接受客户端发回的响应
HttpResponse httpResponse=httpClient.execute(request);
intstatusCode=httpResponse.getStatusLine().getStatusCode();
if(statusCode==HttpStatus.SC_OK){
//得到客户段响应的实体内容
HttpEntity responseHttpEntity=httpResponse.getEntity();
//得到输入流
InputStream in=responseHttpEntity.getContent();
//得到输入流的内容
result=getData(in);
}
Log.d(TAG, statusCode+"");
returnresult;
}

post 操作


几个额外的辅助方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
* 读取返回的信息
* @param in
* @return
*/
privateString getData(InputStream in) {
String result="";
StringBuilder sb=newStringBuilder();
BufferedReader br = newBufferedReader(newInputStreamReader(in));
String line = "";
try{
while((line = br.readLine()) != null) {
//result = result + line;
sb.append(line);
}
br.close();
}catch(Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(result != null) {
try{
br.close();
}catch(IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
returnsb.toString();
}


?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<b>/**
* 输入流转换成字符串
* @param is: 输入流
* @return 字符串对象
*/
privatestatic String InputStreamToString(InputStream is){
BufferedReader reader = null;
StringBuffer responseText = null;
String readerText = null;
try{
reader = newBufferedReader(newInputStreamReader(is, "UTF-8"));
responseText = newStringBuffer();
readerText = reader.readLine();
while(readerText != null){
responseText.append(readerText);
responseText.append(System.getProperty("line.separator"));
readerText = reader.readLine();
}
}catch(UnsupportedEncodingException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}
returnresponseText.toString();
}</b>

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* 将cookie写入指定文件
* @param cookies: cookie
* @param fileName: 文件名
*/
privatestatic void write(Cookie[] cookies, String fileName){
try{
String path = System.getProperty("user.home") + "\\"+ fileName;
File file = newFile(path);
BufferedWriter bw = newBufferedWriter(newFileWriter(file));
for(Cookie c : cookies){
bw.append(c.toString());
bw.append(System.getProperty("line.separator"));
}
bw.flush();
bw.close();
Runtime.getRuntime().exec("explorer " + path + "");
}catch(IOException e) {
e.printStackTrace();
}
}

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
如何 post json格式的数据,并附加http头,接受返回数据,请看下面的代码:
[java] view plaincopy
privatevoid HttpPostData() {
try{
HttpClient httpclient = newDefaultHttpClient();
String uri = "http://www.yourweb.com";
HttpPost httppost = newHttpPost(uri);
//添加http头信息
httppost.addHeader("Authorization","your token");//认证token
httppost.addHeader("Content-Type","application/json");
httppost.addHeader("User-Agent","imgfornote");
//http post的json数据格式: {"name": "your name","parentId": "id_of_parent"}
JSONObject obj = newJSONObject();
obj.put("name","your name");
obj.put("parentId","your parentid");
httppost.setEntity(newStringEntity(obj.toString()));
HttpResponse response;
response = httpclient.execute(httppost);
//检验状态码,如果成功接收数据
intcode = response.getStatusLine().getStatusCode();
if(code == 200) {
String rev = EntityUtils.toString(response.getEntity());//返回json格式: {"id": "27JpL~j4vsL0LX00E00005","version": "abc"}
obj = newJSONObject(rev);
String id = obj.getString("id");
String version = obj.getString("version");
}
}catch(ClientProtocolException e) {
}catch(IOException e) {
}catch(Exception e) {
}
}
主要用到的类有:org.apache.http.client.HttpClient 、org.apache.http.client.methods.HttpPost 和 org.json.JSONObject


请求行 ,是一个方法符号开头 ,后面跟着请求 URI和协议的版本, 以CRLF作为结尾 . 请求后以空格分隔. 除了作为结尾的 CRLF(回车换行)外,不允许出现单独的CR和LF字符,格式如下:
Method Request-URI HTTP-Version CRLF
例如 : GET /test.html HTTP/1.1 (CRLF)
HTTP请求方法 : GET POST HEAD DELETE PUT
POST方法用于向服务器发送请求,要求服务器接受附在请求后面的数据.POST方法在表单提交的时候用的最多 .
例如:
POST /login.jsp HTTP/1.1 (CRLF)
Accept:image/gif (CRLF) (...)
........
Host:www.sample.com (CRLF)
(CRLF)
username=hell@password=123456 两个(CRLF)之后加上参数
HEAD方法只是请求消息报头,而不是完整的内容. 通常用于测试超链接的有效性.

HTTP响应
HTTP-Version Status-Code Reason-Phrase CRLF
例如 : HTTP/1.1 200 OK (CRLF)

状态分类
1xx 提示信息
2xx 请求成功
3xx 重定向
4xx 客户端错误
5xx 服务器错误
HTTP消息有客户端到服务器的请求和服务器到客户端的响应组成.
消息都是由开始行,消息报头(可选),空行(只有CRLF的行),消息正文(可选)组成.
对于请求消息,开始行就是请求行,对于响应消息,开始行就是状态行.

Apache HttpClient是很方便的 Java 开源的访问 HTTP 资源的组件。网站上的资源不总是能匿名访问的,很多都需要登陆后才能操作,且不说论坛里登陆后才能发言,就是某些稍显敏感的 XML 等信息也是登陆后才能获取到的。

没问题,HttpClient 能让你做到,它提供了 Basic 和 Form-Based 两种验证方式。登陆后获得服务器端发来的 Cookie 作为下一次访问的凭证, 让服务端认为你还是个合法用户。服务端不是用 Session 来维护会话的吗?是的,Session 也要有个载体,Cookie 了。或有时 Java Web 会用 jsessionid 参数在服务端与客户端来回关联 Session 信息,也没问题,HttpClient 同样能胜任。

下面主要说明 Form-Based 的验证方式,Basic 的验证简单列了几行代码,还未实践,具体可参考文后的链接。

看 Form-Based 方式的演示代码,如果登陆时需要一个验证码的话,那只有自己想办法怎么得到这个码了,登陆时谁都想无码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
packagecc.unmi.httpclient;
importorg.apache.commons.httpclient.Cookie;
importorg.apache.commons.httpclient.HttpClient;
importorg.apache.commons.httpclient.NameValuePair;
importorg.apache.commons.httpclient.cookie.CookiePolicy;
importorg.apache.commons.httpclient.methods.GetMethod;
importorg.apache.commons.httpclient.methods.PostMethod;
importorg.junit.Test;
publicclass HttpClientLogin {
publicstatic void main(String[] args){
//登陆 Url
String loginUrl = "http://localhost/unmi/login.html";
//需登陆后访问的 Url
String dataUrl = "http://localhost/unmi/user_info.html?userid=123456";
HttpClient httpClient = newHttpClient();
//模拟登陆,按实际服务器端要求选用 Post 或 Get 请求方式
PostMethod postMethod = newPostMethod(loginUrl);
//设置登陆时要求的信息,一般就用户名和密码,验证码自己处理了
NameValuePair[] data = {
newNameValuePair("username","Unmi"),
newNameValuePair("password","123456"),
newNameValuePair("code","anyany")
};
postMethod.setRequestBody(data);
try{
//设置 HttpClient 接收 Cookie,用与浏览器一样的策略
httpClient.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
httpClient.executeMethod(postMethod);
//获得登陆后的 Cookie
Cookie[] cookies=httpClient.getState().getCookies();
String tmpcookies= "";
for(Cookie c:cookies){
tmpcookies += c.toString()+";";
}
//进行登陆后的操作
GetMethod getMethod = newGetMethod(dataUrl);
//每次访问需授权的网址时需带上前面的 cookie 作为通行证
getMethod.setRequestHeader("cookie",tmpcookies);
//你还可以通过 PostMethod/GetMethod 设置更多的请求后数据
//例如,referer 从哪里来的,UA 像搜索引擎都会表名自己是谁,无良搜索引擎除外
postMethod.setRequestHeader("Referer","http://unmi.cc");
postMethod.setRequestHeader("User-Agent","Unmi Spot");
httpClient.executeMethod(getMethod);
//打印出返回数据,检验一下是否成功
String text = getMethod.getResponseBodyAsString();
System.out.println(text);
}catch(Exception e) {
e.printStackTrace();
}
}
}
Basic 验证的简单代码导引,还未亲试:
HttpClient client = newHttpClient();
// 1
client.getState().setCredentials(
newAuthScope("unmi.cc",80, AuthScope.ANY_REALM),
newUsernamePasswordCredentials("username","password")
);
// 2
client.getParams().setAuthenticationPreemptive(true);
// 3
GetMethod getMothod = newGetMethod("http://unmi.cc/twitter");
// 4
getMothod.setDoAuthentication(true);
// 5
intstatus = client.executeMethod( getMothod );

http://unmi.cc/httpclient-login-session

999999999999999999999999

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
post步骤 解析json数据(向服务器传递,接受服务器传递))
www.MyException.Cn 发布于:2012-08-1120:50:31浏览:13
httpClient post方法 解析json数据(向服务器传递,接受服务器传递))
publicclass json extendsActivity {
publicContext context;
privateTextView textView1;
publicstatic String URL = "http://webservice.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl";
privateDefaultHttpClient httpClient;
StringBuilder result = newStringBuilder();
privatestatic final int TIMEOUT = 60;
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
HttpParams paramsw = createHttpParams();
httpClient = newDefaultHttpClient(paramsw);
HttpPost post = newHttpPost( "http://webservice.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl");
List<NameValuePair> params = newArrayList<NameValuePair>();
params.add(newBasicNameValuePair("name","this is post"));
try{
//向服务器写json
JSONObject json = newJSONObject();
Object email = null;
json.put("email", email);
Object pwd = null;
json.put("password", pwd);
StringEntity se = newStringEntity( "JSON: " + json.toString());
se.setContentEncoding(newBasicHeader(HTTP.CONTENT_TYPE, "application/json"));
post.setEntity(se);
post.setEntity(newUrlEncodedFormEntity(params, HTTP.UTF_8));
HttpResponse httpResponse = httpClient.execute(post);
inthttpCode = httpResponse.getStatusLine().getStatusCode();
if(httpCode == HttpURLConnection.HTTP_OK&&httpResponse!=null) {
Header[] headers = httpResponse.getAllHeaders();
HttpEntity entity = httpResponse.getEntity();
Header header = httpResponse.getFirstHeader("content-type");
//读取服务器返回的json数据(接受json服务器数据)
InputStream inputStream = entity.getContent();
InputStreamReader inputStreamReader = newInputStreamReader(inputStream);
BufferedReader reader = newBufferedReader(inputStreamReader);// 读字符串用的。
String s;
while(((s = reader.readLine()) != null)) {
result.append(s);
}
reader.close();// 关闭输入流
//在这里把result这个字符串个给JSONObject。解读里面的内容。
JSONObject jsonObject = newJSONObject(result.toString());
String re_username = jsonObject.getString("username");
String re_password = jsonObject.getString("password");
intre_user_id = jsonObject.getInt("user_id");
setTitle("用户id_"+re_user_id);
Log.v("url response","true="+re_username);
Log.v("url response","true="+re_password);
}else{
textView1.setText("Error Response" + httpResponse.getStatusLine().toString());
}
}catch(UnsupportedEncodingException e) {
}catch(ClientProtocolException e) {
}catch(IOException e) {
}catch(JSONException e) {
e.printStackTrace();
}finally{
if(httpClient != null) {
httpClient.getConnectionManager().shutdown();// 最后关掉链接。
httpClient = null;
}
}
}
publicstatic final HttpParams createHttpParams() {
finalHttpParams params = newBasicHttpParams();
HttpConnectionParams.setStaleCheckingEnabled(params,false);
HttpConnectionParams.setConnectionTimeout(params, TIMEOUT * 1000);
HttpConnectionParams.setSoTimeout(params, TIMEOUT * 1000);
HttpConnectionParams.setSocketBufferSize(params,8192* 5);
returnparams;
}
}

348888888888888888

HttpClient程序包是一个实现了 HTTP 协议的客户端编程工具包,要想熟练的掌握它,必须熟悉 HTTP协议。一个最简单的调用如下:

import java.io.IOException;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
public class Test {
public static void main(String[] args) {
// 核心应用类
HttpClient httpClient = new DefaultHttpClient();
// HTTP请求
HttpUriRequest request =
new HttpGet("http://localhost/index.html");
// 打印请求信息
System.out.println(request.getRequestLine());
try {
// 发送请求,返回响应
HttpResponse response = httpClient.execute(request);
// 打印响应信息
System.out.println(response.getStatusLine());
} catch (ClientProtocolException e) {
// 协议错误
e.printStackTrace();
} catch (IOException e) {
// 网络异常
e.printStackTrace();
}
}
}
如果HTTP服务器正常并且存在相应的服务,则上例会打印出两行结果:
GET http://localhost/index.html HTTP/1.1
HTTP/1.1 200 OK
核心对象httpClient的调用非常直观,其execute方法传入一个request对象,返回一个response对象。使用 httpClient发出HTTP请求时,系统可能抛出两种异常,分别是ClientProtocolException和IOException。第一种异常的发生通常是协议错误导致,如在构造HttpGet对象时传入的协议不对(例如不小心将”http”写成”htp”),或者服务器端返回的内容不符合HTTP协议要求等;第二种异常一般是由于网络原因引起的异常,如HTTP服务器未启动等。
从实际应用的角度看,HTTP协议由两大部分组成:HTTP请求和HTTP响应。那么HttpClient程序包是如何实现HTTP客户端应用的呢?实现过程中需要注意哪些问题呢?
HTTP请求
HTTP 1.1由以下几种请求组成:GET, HEAD, POST, PUT, DELETE, TRACE and OPTIONS, 程序包中分别用HttpGet, HttpHead, HttpPost, HttpPut, HttpDelete, HttpTrace, and HttpOptions 这几个类创建请求。所有的这些类均实现了HttpUriRequest接口,故可以作为execute的执行参数使用。
所有请求中最常用的是GET与POST两种请求,与创建GET请求的方法相同,可以用如下方法创建一个POST请求:
HttpUriRequest request = new HttpPost(
"http://localhost/index.html");
HTTP请求格式告诉我们,有两个位置或者说两种方式可以为request提供参数:request-line方式与request-body方式。
request-line
request-line方式是指在请求行上通过URI直接提供参数。
(1)
我们可以在生成request对象时提供带参数的URI,如:
HttpUriRequest request = new HttpGet(
"http://localhost/index.html?param1=value1&param2=value2");
(2)
另外,HttpClient程序包为我们提供了URIUtils工具类,可以通过它生成带参数的URI,如:
URI uri = URIUtils.createURI("http", "localhost", -1, "/index.html",
"param1=value1&param2=value2", null);
HttpUriRequest request = new HttpGet(uri);
System.out.println(request.getURI());
上例的打印结果如下:
http://localhost/index.html?param1=value1&param2=value2
(3)
需要注意的是,如果参数中含有中文,需将参数进行URLEncoding处理,如:
String param = "param1=" + URLEncoder.encode("中国", "UTF-8") + "&param2=value2";
URI uri = URIUtils.createURI("http", "localhost", 8080,
"/sshsky/index.html", param, null);
System.out.println(uri);
上例的打印结果如下:
http://localhost/index.html?param1=%E4%B8%AD%E5%9B%BD&param2=value2
(4)
对于参数的URLEncoding处理,HttpClient程序包为我们准备了另一个工具类:URLEncodedUtils。通过它,我们可以直观的(但是比较复杂)生成URI,如:
List params = new ArrayList();
params.add(new BasicNameValuePair("param1", "中国"));
params.add(new BasicNameValuePair("param2", "value2"));
String param = URLEncodedUtils.format(params, "UTF-8");
URI uri = URIUtils.createURI("http", "localhost", 8080,
"/sshsky/index.html", param, null);
System.out.println(uri);
上例的打印结果如下:
http://localhost/index.html?param1=%E4%B8%AD%E5%9B%BD&param2=value2
request-body
与request-line方式不同,request-body方式是在request-body中提供参数,此方式只能用于POST请求。在 HttpClient程序包中有两个类可以完成此项工作,它们分别是UrlEncodedFormEntity类与MultipartEntity类。这两个类均实现了HttpEntity接口。
(1)
使用最多的是UrlEncodedFormEntity类。通过该类创建的对象可以模拟传统的HTML表单传送POST请求中的参数。如下面的表单:
<form action="http://localhost/index.html" method="POST">
<input type="text" name="param1" value="中国"/>
<input type="text" name="param2" value="value2"/>
<inupt type="submit" value="submit"/>
</form>
我们可以用下面的代码实现:
List formParams = new ArrayList();
formParams.add(new BasicNameValuePair("param1", "中国"));
formParams.add(new BasicNameValuePair("param2", "value2"));
HttpEntity entity = new UrlEncodedFormEntity(formParams, "UTF-8");
HttpPost request = new HttpPost(“http://localhost/index.html”);
request.setEntity(entity);
当然,如果想查看HTTP数据格式,可以通过HttpEntity对象的各种方法取得。如:
List formParams = new ArrayList();
formParams.add(new BasicNameValuePair("param1", "中国"));
formParams.add(new BasicNameValuePair("param2", "value2"));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formParams, "UTF-8");
System.out.println(entity.getContentType());
System.out.println(entity.getContentLength());
System.out.println(EntityUtils.getContentCharSet(entity));
System.out.println(EntityUtils.toString(entity));
上例的打印结果如下:
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
39
UTF-8
param1=%E4%B8%AD%E5%9B%BD&param2=value2
(2)
除了传统的application/x-www-form-urlencoded表单,我们另一个经常用到的是上传文件用的表单,这种表单的类型为 multipart/form-data。在HttpClient程序扩展包(HttpMime)中专门有一个类与之对应,那就是 MultipartEntity类。此类同样实现了HttpEntity接口。如下面的表单:
<form action="http://localhost/index.html" method="POST"
enctype="multipart/form-data">
<input type="text" name="param1" value="中国"/>
<input type="text" name="param2" value="value2"/>
<input type="file" name="param3"/>
<inupt type="submit" value="submit"/>
</form>
我们可以用下面的代码实现:
MultipartEntity entity = new MultipartEntity();
entity.addPart("param1", new StringBody("中国", Charset.forName("UTF-8")));
entity.addPart("param2", new StringBody("value2", Charset.forName("UTF-8")));
entity.addPart("param3", new FileBody(new File("C:\\1.txt")));
HttpPost request = new HttpPost(“http://localhost/index.html”);
request.setEntity(entity);
HTTP响应
HttpClient程序包对于HTTP响应的处理较之HTTP请求来说是简单多了,其过程同样使用了HttpEntity接口。我们可以从 HttpEntity对象中取出数据流(InputStream),该数据流就是服务器返回的响应数据。需要注意的是,HttpClient程序包不负责解析数据流中的内容。如:
HttpUriRequest request = ...;
HttpResponse response = httpClient.execute(request);
// 从response中取出HttpEntity对象
HttpEntity entity = response.getEntity();
// 查看entity的各种指标
System.out.println(entity.getContentType());
System.out.println(entity.getContentLength());
System.out.println(EntityUtils.getContentCharSet(entity));
// 取出服务器返回的数据流
InputStream stream = entity.getContent();
// 以任意方式操作数据流stream
// 调用方式 略
附注:
本文说明的是HttpClient 4.0.1,该程序包(包括依赖的程序包)由以下几个JAR包组成:
commons-logging-1.1.1.jar
commons-codec-1.4.jar
httpcore-4.0.1.jar
httpclient-4.0.1.jar
apache-mime4j-0.6.jar
httpmime-4.0.1.jar
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

现在Apache已经发布了:HttpCore 4.0-beta3、HttpClient 4.0-beta1。
到此处可以去下载这些源代码:http://hc.apache.org/downloads.cgi
另外,还需要apache-mime4j-0.5.jar 包。
在这里先写个简单的POST方法。
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
packagetest;
importjava.util.ArrayList;
importjava.util.List;
importorg.apache.http.Header;
importorg.apache.http.HttpEntity;
importorg.apache.http.HttpResponse;
importorg.apache.http.NameValuePair;
importorg.apache.http.client.entity.UrlEncodedFormEntity;
importorg.apache.http.client.methods.HttpPost;
importorg.apache.http.client.params.CookiePolicy;
importorg.apache.http.client.params.ClientPNames;
importorg.apache.http.impl.client.DefaultHttpClient;
importorg.apache.http.message.BasicNameValuePair;
importorg.apache.http.protocol.HTTP;
importorg.apache.http.util.EntityUtils;
publicclass Test2 {
publicstatic void main(String[] args) throwsException {
DefaultHttpClient httpclient = newDefaultHttpClient(); //实例化一个HttpClient
HttpResponse response = null;
HttpEntity entity = null;
httpclient.getParams().setParameter(
ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY); //设置cookie的兼容性
HttpPost httpost = newHttpPost("http://127.0.0.1:8080/pub/jsp/getInfo"); //引号中的参数是:servlet的地址
List <NameValuePair> nvps = newArrayList <NameValuePair>();
nvps.add(newBasicNameValuePair("jqm","fb1f7cbdaf2bf0a9cb5d43736492640e0c4c0cd0232da9de"));
// BasicNameValuePair("name", "value"), name是post方法里的属性, value是传入的参数值
nvps.add(newBasicNameValuePair("sqm","1bb5b5b45915c8"));
httpost.setEntity(newUrlEncodedFormEntity(nvps, HTTP.UTF_8)); //将参数传入post方法中
response = httpclient.execute(httpost); //执行
entity = response.getEntity();//返回服务器响应
try{
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());//服务器返回状态
Header[] headers = response.getAllHeaders(); //返回的HTTP头信息
for(inti=0; i<headers.length; i++) {
System.out.println(headers[i]);
}
System.out.println("----------------------------------------");
String responseString = null;
if(response.getEntity() != null) {
responseString = EntityUtils.toString(response.getEntity()); / /返回服务器响应的HTML代码
System.out.println(responseString);//打印出服务器响应的HTML代码
}
}finally{
if(entity != null)
entity.consumeContent();// release connection gracefully
}
System.out.println("Login form get: " + response.getStatusLine());
if(entity != null) {
entity.consumeContent();
}
}
}


HttpClient4.0 学习实例 - 页面获取
HttpClient 4.0出来不久,所以网络上面相关的实例教程不多,搜httpclient得到的大部分都是基于原 Commons HttpClient 3.1 (legacy) 包的,官网下载页面:http://hc.apache.org/downloads.cgi,如果大家看了官网说明就明白httpclient4.0是从原包分支出来独立成包的,以后原来那个包中的httpclient不会再升级,所以以后我们是用httpclient新分支,由于4.0与之前的3.1包结构以及接口等都有较大变化,所以网上搜到的实例大部分都是不适合4.0的,当然,我们可以通过那些实例去琢磨4.0的用法,我也是新手,记录下学习过程方便以后检索
本实例我们来获取抓取网页编码,内容等信息
默认情况下,服务器端会根据客户端的请求头信息来返回服务器支持的编码,像google.cn他本身支持utf-8,gb2312等编码,所以如果你在头部中不指定任何头部信息的话他默认会返回gb2312编码,而如果我们在浏览器中直接访问google.cn,通过httplook,或者firefox 的firebug插件查看返回头部信息的话会发现他返回的是UTF-8编码
下面我们还是看实例来解说吧,注释等我也放代码里面解释,放完整代码,方便新手理解
本实例将
使用的httpclient相关包
httpclient-4.0.jar
httpcore-4.0.1.jar
httpmime-4.0.jar
commons-logging-1.0.4.jar等其它相关包
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// HttpClientTest.java
packagecom.baihuo.crawler.test;
importjava.util.regex.Matcher;
importjava.util.regex.Pattern;
importorg.apache.http.Header;
importorg.apache.http.HttpEntity;
importorg.apache.http.HttpHost;
importorg.apache.http.HttpResponse;
importorg.apache.http.client.HttpClient;
importorg.apache.http.client.methods.HttpGet;
importorg.apache.http.impl.client.DefaultHttpClient;
importorg.apache.http.util.EntityUtils;
classHttpClientTest {
publicfinal static void main(String[] args) throwsException {
// 初始化,此处构造函数就与3.1中不同
HttpClient httpclient = newDefaultHttpClient();
HttpHost targetHost = newHttpHost("www.google.cn");
//HttpGet httpget = new HttpGet("http://www.apache.org/");
HttpGet httpget = newHttpGet("/");
// 查看默认request头部信息
System.out.println("Accept-Charset:"+ httpget.getFirstHeader("Accept-Charset"));
// 以下这条如果不加会发现无论你设置Accept-Charset为gbk还是utf-8,他都会默认返回gb2312(本例针对google.cn来说)
httpget.setHeader("User-Agent","Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.1.2)");
// 用逗号分隔显示可以同时接受多种编码
httpget.setHeader("Accept-Language","zh-cn,zh;q=0.5");
httpget.setHeader("Accept-Charset","GB2312,utf-8;q=0.7,*;q=0.7");
// 验证头部信息设置生效
System.out.println("Accept-Charset:"+ httpget.getFirstHeader("Accept-Charset").getValue());
// Execute HTTP request
System.out.println("executing request " + httpget.getURI());
HttpResponse response = httpclient.execute(targetHost, httpget);
//HttpResponse response = httpclient.execute(httpget);
System.out.println("----------------------------------------");
System.out.println("Location: " + response.getLastHeader("Location"));
System.out.println(response.getStatusLine().getStatusCode());
System.out.println(response.getLastHeader("Content-Type"));
System.out.println(response.getLastHeader("Content-Length"));
System.out.println("----------------------------------------");
// 判断页面返回状态判断是否进行转向抓取新链接
intstatusCode = response.getStatusLine().getStatusCode();
if((statusCode == HttpStatus.SC_MOVED_PERMANENTLY) ||
(statusCode == HttpStatus.SC_MOVED_TEMPORARILY) ||
(statusCode == HttpStatus.SC_SEE_OTHER) ||
(statusCode == HttpStatus.SC_TEMPORARY_REDIRECT)) {
// 此处重定向处理 此处还未验证
String newUri = response.getLastHeader("Location").getValue();
httpclient = newDefaultHttpClient();
httpget = newHttpGet(newUri);
response = httpclient.execute(httpget);
}
// Get hold of the response entity
HttpEntity entity = response.getEntity();
// 查看所有返回头部信息
Header headers[] = response.getAllHeaders();
intii = 0;
while(ii < headers.length) {
System.out.println(headers[ii].getName() + ": " + headers[ii].getValue());
++ii;
}
// If the response does not enclose an entity, there is no need
// to bother about connection release
if(entity != null) {
// 将源码流保存在一个byte数组当中,因为可能需要两次用到该流,
byte[] bytes = EntityUtils.toByteArray(entity);
String charSet = "";
// 如果头部Content-Type中包含了编码信息,那么我们可以直接在此处获取
charSet = EntityUtils.getContentCharSet(entity);
System.out.println("In header: " + charSet);
// 如果头部中没有,那么我们需要 查看页面源码,这个方法虽然不能说完全正确,因为有些粗糙的网页编码者没有在页面中写头部编码信息
if(charSet == "") {
regEx="(?=<meta).*?(?<=charset=[\\'|\\\"]?)([[a-z]|[A-Z]|[0-9]|-]*)";
p=Pattern.compile(regEx, Pattern.CASE_INSENSITIVE);
m=p.matcher(newString(bytes)); // 默认编码转成字符串,因为我们的匹配中无中文,所以串中可能的乱码对我们没有影响
result=m.find();
if(m.groupCount() == 1) {
charSet = m.group(1);
}else{
charSet = "";
}
}
System.out.println("Last get: " + charSet);
// 至此,我们可以将原byte数组按照正常编码专成字符串输出(如果找到了编码的话)
System.out.println("Encoding string is: " + newString(bytes, charSet));
}
httpclient.getConnectionManager().shutdown();
}
}
分享到:
评论

相关推荐

    HTTPClient工具类,完整

    HTTPClient工具类,完整,HTTPClient工具类,完整,HTTPClient工具类,完整HTTPClient工具类,完整,HTTPClient工具类,完整

    httpClientUtil工具类

    httpClientUtil工具类

    HttpClientHelper 工具类

    HttpClientHelper 是一个C#编写的工具类,主要目的是简化HTTP客户端操作,提供同步和异步的请求方法,返回数据格式多样,包括字符串、泛型类型和XML。在爬虫开发中,这样的工具类非常实用,因为爬虫经常需要与各种...

    httpclient4.3工具类

    在这个`httpclient4.3工具类`中,我们看到的是一个自定义的`httpclientUtils`,它是为了满足特定项目需求而编写的,集成了常见的HTTP操作。 HttpClient 4.3主要知识点包括: 1. **连接管理**:HttpClient 4.3引入...

    HttpClient接口调用工具类(附带demo)

    总之,这个HttpClient工具类提供了一个简洁易用的接口,帮助开发者快速、方便地进行HTTP请求,无论是在进行API调用还是数据交互,都能大大简化工作流程。通过这个工具类,你无需深入了解HttpClient的底层实现,只需...

    java httpClient 工具类 java httpClient 工具类

    java httpClient 工具类 java httpClient 工具类 java httpClient 工具类 java httpClient 工具类 java httpClient 工具类 java httpClient 工具类 java httpClient 工具类 java httpClient 工具类 java httpClient ...

    HttpClientUtil工具类发送get和post请求,支持http和https,支持发送文件

    首先,HttpClientUtil工具类通常会封装HttpClient的基本操作,以便于开发者在应用中便捷地调用。GET和POST请求是HTTP协议中最常见的两种请求方法。GET请求用于获取服务器上的资源,而POST请求则常用于向服务器提交...

    httpclient接口工具类

    利用httpclient封装了http的POST和GET请求方式,封装方法多样,返回结果为json

    HttpClient 4.5 封装的工具类 HttpUtil 可用于爬虫和模拟登陆

    基于Apache HttpClient 4.5.2 封装的工具类 HttpUtil 可用于爬虫和模拟登陆。使用新的语法后比3.*版本的速度感觉有提升。使用后注意资源的释放 pom 部分,应该不全,需要用的根据代码的import去找maven资源即可。 ...

    HttpClientUtil工具类

    HttpClientUtil工具类

    Android HttpClient工具类

    7. **EntityUtils**:一个工具类,用于处理响应实体,如读取响应内容。例如: ```java String responseBody = EntityUtils.toString(response.getEntity()); ``` 8. **HttpContext**:提供了请求执行的上下文...

    HttpClient工具类

    总之,HttpClient工具类是为了简化HTTP通信而设计的,它封装了HttpClient的基本操作,提供了更便捷的API,使得在Java应用中发送HTTP请求变得更加容易。通过理解上述关键功能,我们可以更好地利用这个工具类进行网络...

    httpclient 工具类

    httpclient pool 工具类,修改ip,请求时间

    httpclient4.3 封装工具类

    HttpClient是Apache基金会开发的一个HTTP客户端库,主要用于处理HTTP请求。HttpClient 4.3版本是对该库的一次重要...了解这些知识点,可以帮助我们更好地利用HttpClient 4.3封装工具类,高效、稳定地进行HTTP请求操作。

    高效池化-JAVA-HttpClient工具类

    1.高效简单池化的HttpClient工具类,提供单元测试用列。 2.支持基于SpringBoot 2.1.x的自动装载模块,引用依赖即可使用。 3.公司几十个项目都使用该工具类访问第三方的Http/Https+json协议接口。 4.经过上市公司多个...

    在java后端发送HTTPClient请求工具类

    在实现上,HTTPClient提供了丰富的API来处理各种HTTP操作,但其API通常较为底层,因此在工具类中会通过封装这些API来提供一个更加简洁和直观的接口。例如,可能使用Java 8的Lambda表达式或Stream API来简化对请求和...

    HttpClient请求工具类 4.3

    适用于多线程的Httpclient请求的工具类

    HttpClientUtil工具类 里面包含GET POST 及返回值处理

    这个工具类的主要优点在于它可以帮助开发者快速地构建网络请求,无需深入了解HttpClient库的所有细节。下面将详细解释HttpClientUtil的主要功能和使用方法。 1. **HttpClient介绍**: Apache HttpClient是一个Java...

    httpclient4.3 封装工具类.zip

    综上所述,这个“httpclient4.3 封装工具类.zip”应该包含了一些实用的类,将HttpClient的基本操作进行了封装,方便开发者在处理HTTP请求时直接调用,提高开发效率和代码可维护性。使用这样的工具类,开发者可以更...

Global site tag (gtag.js) - Google Analytics