Java 库支持更高级别处理,而不只是创建套接字连接发送 HTTP 请求。
Java 库与网页交互并不是特别方便,可以考虑使用其他库,如 HttpClient、Feign、RestTemplate
1 URL
URL 和 URLConnection 封装了大量实现细节。
1.1 创建 URL
URL url = new URL(urlString);
1.2 获取资源
InputStream inStream = url.openStream();
Scanner in = new Scanner(inStream, "UTF-8");
2 URI
URL 是 URI 的一个特例,在 Java 中,URI 类唯一作用是解析。
2.1 解析标识符
URI 的作用之一是解析标识符,并将它分解成不同组成部分,并提供方法读取这些部分。
1)URI 句法
一个 URI 具有以下句法,[...]
表示可选部分
[scheme:]schemeSpecificPart[#fragment]
- 绝对URI
包含[scheme:]
- 透明的
schemeSpecificPart
以/
开头 - 不透明的
schemeSpecificPart
不以/
开头
- 透明的
- 相对URI
不包含[scheme:]
2)分层
所有绝对的透明的URI
和所有相对URI
都是分层的。
分层URI的schemeSpecificPart
部分具有以下结构
[//authority][path][?query]
对于基于服务器的URI,authority具有以下形式
[uer-info@]host[:port]
2.2 处理标识符
1)解析相对URL
URI base = new URI("http://docs.mycompany.com/api/java/lang/Integer.html");
URI relative = new URI(".../java/lang/String.html");
URI combined = base.resolve(relative);
//combined ==> "http://docs.mycompany.com/api/java/lang/String.html"
2)相对化
URI base = new URI("http://docs.mycompany.com/api");
URI combined = new URI("http://docs.mycompany.com/api/java/lang/String.html");
URI relative = base.relativize(combined);
//relative ==> "/java/lang/String.html"
3 URLConnection
URLConnection 类比 URL 类功能更多。
- 获取连接对象
URLConnection connection = url.openConnection();
- 设置请求属性
connection.setConnectTimeout(1000);
//默认连接只产生从服务器获取信息的输入流,如想获得输出流,得设置
connection.setDoOutput(true);
//使用缓存
connection.setUseCaches(true);
//设置header
connection.setRequestProperty("","");
...
- 建立连接
connection.connect();
- 建立连接后可以查询头信息
getHeaderFields
getHeaderField
getDate
...
- 访问资源
connection.getInputStream();
4 提交表单数据
4.1 GET
参数直接跟在 URL 结尾
参数编码
- 保留字符
A-z
,0-9
,以及.-~_
。 - 用
+
替换所有空格 - 将其他所有字符编码为 UTF-8,并将每个字节都编码为
%
后面紧跟一个2位十六进制数字
例如:San Francisco, CA ==> San+Francisco%2c+CA
4.2 POST
1)参数
从 URLConnection 获取输出流,并将参数写入该输出流。仍需URL编码
URL url = new URL("http://host/path");
URLConnection connection = url.openConnection();
//获取输出流
connection.setDoOutput(true);
PrintWrite out = new PrintWrite(connection.getOutputStream(), "UTF-8");
//发送数据
out.print(name1 + "=" + URLEncoder.encode(value1, "UTF-8") + "&");
out.print(name2 + "=" + URLEncoder.encode(value2, "UTF-8"));
//关闭输出流
out.close();
//读取服务器响应
connection.getInputStream();
2)捕捉错误页
InputStream err = ((HttpURLConnection)connection).getErrorStream();
3)cookie
配置全局处理器
CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
4)人工重定向
自动重定向不会使用最初请求中的用户代理设置,可人工处理
- 关闭自动重定向
connection.setInstanceFollowRedirects(false);
- 发送请求后,获取响应码
int responseCode = connection.getResponseCode();
如果响应值属于 301、302、303 则是重定向
HttpURLConnection.HTTP_MOVED_PERM;//301
HttpURLConnection.HTTP_MOVED_TEMP;//302
HttpURLConnection.HTTP_SEE_OTHER;//303
- 获取重定向URL,断开原有连接,创建到新URL的连接
String location = connection.getHeaderField("Location");
if(location != null){
URL base = connection.getURL();
connection.disconnect();
connection = (HttpURLConnection) new URL(base, location).openConnection();
}