public abstract class HttpURLConnection extends URLConnection
支持 HTTP 特定功能的 URLConnection,如设置请求方法(GET、POST等)
每个 HttpURLConnection 实例都可用于生成单个请求,但是其他实例可以透明地共享连接到 HTTP 服务器的基础网络。请求后在 HttpURLConnection 的 InputStream 或 OutputStream 上调用 close() 方法可以释放与此实例关联的网络资源,但对共享的持久连接没有任何影响。如果在调用 disconnect() 时持久连接空闲,则可能关闭基础套接字。
模拟表单发送GET、POST请求
设置请求方法:setRequestMethod(String method),默认值:GET,可选值:GET 、POST 、HEAD 、OPTIONS、PUT、DELETE 、TRACE
public static String doGet(String url, String params) {
BufferedReader in = null;
try {
String urlString = url + "?" + params;
URL realUrl = new URL(urlString);
// 打开和URL之间的连接
HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
// 设置请求参数
conn.setRequestMethod("GET");// 默认GET,可以不填
conn.setUseCaches(false);
conn.setConnectTimeout(5000); //请求超时时间
// 设置请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
// conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接
conn.connect();
// 获取所有响应头
Map<String, List<String>> map = conn.getHeaderFields();
for (String key : map.keySet()) {
System.out.println(key + "=" + map.get(key));
}
// 获取响应
String line = null;
StringBuffer sb = new StringBuffer();
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = in.readLine()) != null) {
sb.append(line);
}
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (in != null) {
in.close();
in = null;
}
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
模拟发送POST请求,需要设置:
- conn.setDoInput(true),true:从URL连接读取数据
- conn.setDoOutput(true),true:数据写入URL连接
若有参数,建议设置conn.setRequestProperty("Content-Type", xxx),常用值:
- application/x-www-form-urlencoded; charset=UTF-8:普通参数
- multipart/form-data; boundary=----WebKitFormBoundaryLKw1nLEcfWdwlRYH:上传文件,边界值boundary可以自定义
public static String doPost(String url, String params) {
OutputStream out = null;
BufferedReader in = null;
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
// 设置请求参数
conn.setRequestMethod("POST");
conn.setConnectTimeout(5000);
conn.setUseCaches(false);
conn.setDoInput(true);// true:从URL连接读取数据,默认值为true,可以不填
conn.setDoOutput(true);// true:数据写入URL连接,默认值false
// 设置请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
// 设置请求体
out = conn.getOutputStream();
out.write(params.getBytes());
out.flush();
// 建立实际的连接
conn.connect();
// 获取所有响应头
Map<String, List<String>> map = conn.getHeaderFields();
for (String key : map.keySet()) {
System.out.println(key + "=" + map.get(key));
}
// 获取响应
String line = null;
StringBuffer sb = new StringBuffer();
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = in.readLine()) != null) {
sb.append(line);
}
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
in = null;
}
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
3.上传文件示例:
模拟表单上传文件,Content-Type设置为multipart/form-data,即模拟设置表单的enctype属性;其他属性参数参照浏览器发送的请求填写,如边界、传递的属性等。
/**
* 模拟表单上传文件
* @param urlStr 请求的URL
* @param file 文件
* @return 远程资源的响应结果
*/
public static String doUpload(String urlStr, File file) {
OutputStream out = null;
BufferedReader bufr = null;
String result = "";
try {
URL url = new URL(urlStr);
// 打开和URL之间的连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// 设置请求参数
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
// 设置请求属性
conn.setRequestProperty("Accept", "*/*");
conn.setRequestProperty("Connection", "Keep-Alive");
// 定义边界
String boundary = "----" + System.currentTimeMillis();
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
// 获取输出流
out = conn.getOutputStream();
// 请求体
// 1.普通表单
StringBuilder sb = new StringBuilder();
sb.append("--").append(boundary).append("\r\n");// 必须多两道-
sb.append("Content-Disposition: form-data; name=\"name1\"\r\n\r\n");
sb.append("value1\r\n");
out.write(sb.toString().getBytes("UTF-8"));
// 2.
sb = new StringBuilder();
sb.append("--").append(boundary).append("\r\n");// 必须多两道-
sb.append("Content-Disposition: form-data; name=\"name2\"\r\n\r\n");
sb.append("value2\r\n");
out.write(sb.toString().getBytes("UTF-8"));
// 3.文件
sb = new StringBuilder();
sb.append("--").append(boundary).append("\r\n");// 必须多两道-
sb.append("Content-Disposition: form-data; name=\"upload\"; filename=\"" + file.getName() + "\"\r\n");
sb.append("Content-Type: application/octet-stream\r\n\r\n");
out.write(sb.toString().getBytes("UTF-8"));
// 写入文件
BufferedInputStream bufin = new BufferedInputStream(new FileInputStream(file));
int len = 0;
byte[] bytes = new byte[1024];
while ((len = bufin.read(bytes)) != -1) {
out.write(bytes, 0, len);
}
bufin.close();
// 结尾边界
String foot = "\r\n\r\n--" + boundary + "--\r\n";
out.write(foot.getBytes("UTF-8"));
out.flush();
// 读取响应
bufr = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
String line;
while ((line = bufr.readLine()) != null) {
result += line;
}
conn.disconnect();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
if (bufr != null) {
bufr.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return result;
}
浏览器发送的请求: