Java 进行 http 协议的请求主要有三种方式,一是 jdk 1.1 开始自带的 HttpURLConnection 及相关类,二是 apache commons 系列中的 httpclient 工具包,三是 square 公司开源的 OkHttp 工具包。
HttpURLConnection
HttpURLConnection 是 jdk 1.1 开始就加入的 http 工具类,它是一个抽象类,只能通过 url.openConnection() 方法创建具体的实例。严格来说,openConnection() 方法返回的是 URLConnection 的子类。只有 http 或 https 开头的 url 才返回 HttpURLConnection 对象。
GET 请求
HttpURLConnection get 请求示例:
public static String doHttpGet(String httpUrlStr) {
try {
URL url = new URL(httpUrlStr);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
System.out.println("Connection impl class : " + httpConn.getClass());
/**
* 设置请求属性
*/
// 设置请求方式为 GET,默认是 GET,可以不用设置
httpConn.setRequestMethod("GET");
// 设置连接超时时间,单位为毫秒
httpConn.setConnectTimeout(5000);
// 设置读取超时时间,单位为毫秒
httpConn.setReadTimeout(4000);
// 设置长连接,但是这个需要 http 1.1 协议及服务端支持才会真正生效
httpConn.setRequestProperty("Connection", "Keep-Alive");
StringBuilder response = new StringBuilder();
String inputLine;
BufferedReader br = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
while ((inputLine = br.readLine()) != null) {
response.append(inputLine);
}
br.close();
String responseStr = response.toString();
System.out.println("Sending Request to URL : " + httpUrlStr + "\n");
int responseCode = httpConn.getResponseCode();
System.out.println("Response Code : " + responseCode + "\n");
String responseMessage = httpConn.getResponseMessage();
System.out.println("Response Message : " + responseMessage + "\n");
// 打印结果
System.out.println("Response Content : " + responseStr);
return responseStr;
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return null;
}
POST 请求
HttpURLConnection post 请求不同于 get 请求,需要额外设置一些属性,具体示例如下:
public static String doHttpPost(String httpUrlStr, String jsonStr) {
try {
URL url = new URL(httpUrlStr);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
System.out.println("Connection impl class : " + httpConn.getClass());
/**
* 设置请求属性
*/
// 设置请求方式为 POST
httpConn.setRequestMethod("POST");
// 设置请求数据格式,如 json 形式
httpConn.setRequestProperty("Content-Type", "application/json; utf-8");
// 设置接收数据格式,如 json 形式
httpConn.setRequestProperty("Accept", "application/json");
// 对于 post 请求,参数要放在 http 正文内,因此需要设为 true
httpConn.setDoOutput(true);
// 设置连接超时时间,单位为毫秒
httpConn.setConnectTimeout(5000);
// 设置读取超时时间,单位为毫秒
httpConn.setReadTimeout(4000);
// 设置长连接,但是这个需要 http 1.1 协议及服务端支持才会真正生效
httpConn.setRequestProperty("Connection", "Keep-Alive");
/**
* 设置 post 请求体
*/
if (jsonStr != null) {
OutputStream os = httpConn.getOutputStream();
byte[] input = jsonStr.getBytes("utf-8");
os.write(input, 0, input.length);
os.flush();
os.close();
}
StringBuilder response = new StringBuilder();
String inputLine;
BufferedReader br = new BufferedReader(
new InputStreamReader(httpConn.getInputStream(), "utf-8")
);
while ((inputLine = br.readLine()) != null) {
response.append(inputLine);
}
br.close();
String responseStr = response.toString();
System.out.println("Sending Request to URL : " + httpUrlStr + "\n");
int responseCode = httpConn.getResponseCode();
System.out.println("Response Code : " + responseCode + "\n");
String responseMessage = httpConn.getResponseMessage();
System.out.println("Response Message : " + responseMessage + "\n");
// 打印结果
System.out.println("Response Content : " + responseStr);
return responseStr;
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return null;
}
看到如上示例,读者可能会有疑问,真正的 http 请求是在哪个步骤触发的?其实,getOutputStream 和 getInputStream 内部都会隐式的调用 connect(),但是个人建议最好还是显性调用 connect() 方法,从源码可以看出,若多次调用 connect 方法,后面会自动忽略。