在一般情况下,如果只是需要Web站点的某个简单页面提交请求并获取服务器响应,HttpURLConnection完全可以胜任。但在绝大部分情况下,Web站点的网页可能没这么简单,这些页面并不是通过一个简单的URL就可访问的,可能需要用户登录而且具有相应的权限才可访问该页面。在这种情况下,就需要涉及Session、Cookie的处理了,如果打算使用HttpURLConnection来处理这些细节,当然也是可能实现的,只是处理起来难度就大了。
为了更好地处理向Web站点请求,包括处理Session、Cookie等细节问题,Apache开源组织提供了一个HttpClient项目,看它的名称就知道,它是一个简单的HTTP客户端(并不是浏览器),可以用于发送HTTP请求,接收HTTP响应。但不会缓存服务器的响应,不能执行HTML页面中嵌入的JavaScript代码;也不会对页面内容进行任何解析、处理。
简单来说,HttpClient就是一个增强版的HttpURLConnection,HttpURLConnection可以做的事情HttpClient全部可以做;HttpURLConnection没有提供的有些功能,HttpClient也提供了,但它只是关注于如何发送请求、接收
响应,以及管理HTTP连接。
HttpURLConnection实现步骤:
(1).得到HttpURLConnection对象,通过调用URL.openConnection()方法得到该对象
(2).设置请求头属性,比如数据类型,数据长度等等
(3).可选的操作 setDoOutput(true),默认为false无法向外写入数据!setDoInput(true),一般不用设置默认为true
(4).浏览器向服务器发送的数据,比如post提交form表单或者像服务器发送一个文件
(5).浏览器读取服务器发来的相应,包括servlet写进response的头数据(content-type及content-length等等),body数据
(6).调用HttpURLConnection的disconnect()方法, 即设置 http.keepAlive = false;释放资源
(1)Get请求
public static void get() {
HttpURLConnection conn = null;
try {
URL url = new URL("http://127.0.0.1:8080/Day18/servlet/UploadTest");
//1.得到HttpURLConnection实例化对象
conn = (HttpURLConnection) url.openConnection();
//2.设置请求信息(请求方式... ...)
//设置请求方式和响应时间
conn.setRequestMethod("GET");
//conn.setRequestProperty("encoding","UTF-8"); //可以指定编码
conn.setConnectTimeout(5000);
//不使用缓存
conn.setUseCaches(false);
//3.读取相应
if (conn.getResponseCode() == 200) {
//先将服务器得到的流对象 包装 存入缓冲区,忽略了正在缓冲时间
InputStream in = new BufferedInputStream(conn.getInputStream());
// 得到servlet写入的头信息,response.setHeader("year", "2013");
String year = conn.getHeaderField("year");
System.out.println("year="+year);
byte[] bytes = readFromInput(in); //封装的一个方法,通过指定的输入流得到其字节数据
System.out.println(new String(bytes, "utf-8"));
System.out.println("[浏览器]成功!");
} else {
System.out.println("请求失败!");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//4.释放资源
if (conn != null) {
//关闭连接 即设置 http.keepAlive = false;
conn.disconnect();
}
}
}
(2)Post请求
/**
* post请求方式,完成form表单的提交
*/
public static void post() {
HttpURLConnection conn = null;
try {
URL url = new URL("http://127.0.0.1:8080/Day18/servlet/Logining");
String para = new String("username=admin&password=admin");
//1.得到HttpURLConnection实例化对象
conn = (HttpURLConnection) url.openConnection();
//2.设置请求方式
conn.setRequestMethod("POST");
//3.设置post提交内容的类型和长度
/*
* 只有设置contentType为application/x-www-form-urlencoded,
* servlet就可以直接使用request.getParameter("username");直接得到所需要信息
*/
conn.setRequestProperty("contentType","application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", String.valueOf(para.getBytes().length));
//默认为false
conn.setDoOutput(true);
//4.向服务器写入数据
conn.getOutputStream().write(para.getBytes());
//5.得到服务器相应
if (conn.getResponseCode() == 200) {
System.out.println("服务器已经收到表单数据!");
} else {
System.out.println("请求失败!");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//6.释放资源
if (conn != null) {
//关闭连接 即设置 http.keepAlive = false;
conn.disconnect();
}
}
}
HttpClient实现步骤:
- 创建HttpClient对象。
- 如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象
- 如果需要发送请求参数,可调用HttpGet、HttpPost共同的setParams(HetpParams params)方法来添加请求参数;对于HttpPost对象而言,也可调用setEntity(HttpEntity entity)方法来设置请求参数
- 调用HttpClient对象的execute(HttpUriRequest request)发送请求,执行该方法返回一个HttpResponse
- 调用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容
(1)Get请求
/**
httpClient的get请求方式2
* @return
* @throws Exception
*/
public static String doGet(String url, String charset)
throws Exception {
/*
* 使用 GetMethod 来访问一个 URL 对应的网页,实现步骤: 1:生成一个 HttpClinet 对象并设置相应的参数。
* 2:生成一个 GetMethod 对象并设置响应的参数。 3:用 HttpClinet 生成的对象来执行 GetMethod 生成的Get
* 方法。 4:处理响应状态码。 5:若响应正常,处理 HTTP 响应内容。 6:释放连接。
*/
/* 1 生成 HttpClinet 对象并设置参数 */
HttpClient httpClient = new HttpClient();
// 设置 Http 连接超时为5秒
httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
/* 2 生成 GetMethod 对象并设置参数 */
GetMethod getMethod = new GetMethod(url);
// 设置 get 请求超时为 5 秒
getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 5000);
// 设置请求重试处理,用的是默认的重试处理:请求三次
getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler());
String response = "";
/* 3 执行 HTTP GET 请求 */
try {
int statusCode = httpClient.executeMethod(getMethod);
/* 4 判断访问的状态码 */
if (statusCode != HttpStatus.SC_OK) {
System.err.println("请求出错: "+ getMethod.getStatusLine());
}
/* 5 处理 HTTP 响应内容 */
// HTTP响应头部信息,这里简单打印
Header[] headers = getMethod.getResponseHeaders();
for (Header h : headers)
System.out.println(h.getName() + "------------ " + h.getValue());
// 读取 HTTP 响应内容,这里简单打印网页内容
byte[] responseBody = getMethod.getResponseBody();// 读取为字节数组
response = new String(responseBody, charset);
System.out.println("----------response:" + response);
// 读取为 InputStream,在网页内容数据量大时候推荐使用
// InputStream response = getMethod.getResponseBodyAsStream();
} catch (HttpException e) {
// 发生致命的异常,可能是协议不对或者返回的内容有问题
System.out.println("请检查输入的URL!");
e.printStackTrace();
} catch (IOException e) {
// 发生网络异常
System.out.println("发生网络异常!");
e.printStackTrace();
} finally {
/* 6 .释放连接 */
getMethod.releaseConnection();
}
return response;
}
(2)Post请求
1.提交json参数:
/**
* post请求
* @param url
* @param json
* @return
*/
public static JSONObject doPost(String url,JSONObject json){
DefaultHttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(url);
JSONObject response = null;
try {
StringEntity s = new StringEntity(json.toString());
s.setContentEncoding("UTF-8");
s.setContentType("application/json");//发送json数据需要设置contentType
post.setEntity(s);
HttpResponse res = client.execute(post);
if(res.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
HttpEntity entity = res.getEntity();
String result = EntityUtils.toString(res.getEntity());// 返回json格式:
response = JSONObject.fromObject(result);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return response;
}
2.提交 key-value
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
/*
* 利用HttpClient进行post请求的工具类
*/
public class HttpClientUtil {
public String doPost(String url,Map<String,String> map,String charset){
HttpClient httpClient = null;
HttpPost httpPost = null;
String result = null;
try{
httpClient = new SSLClient();
httpPost = new HttpPost(url);
//设置参数
List<NameValuePair> list = new ArrayList<NameValuePair>();
Iterator iterator = map.entrySet().iterator();
while(iterator.hasNext()){
Entry<String,String> elem = (Entry<String, String>) iterator.next();
list.add(new BasicNameValuePair(elem.getKey(),elem.getValue()));
}
if(list.size() > 0){
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list,charset);
httpPost.setEntity(entity);
}
HttpResponse response = httpClient.execute(httpPost);
if(response != null){
HttpEntity resEntity = response.getEntity();
if(resEntity != null){
result = EntityUtils.toString(resEntity,charset);
}
}
}catch(Exception ex){
ex.printStackTrace();
}
return result;
}
}