Java 为网络支持提供了 java.net 包,该包下的 URL 和 URLConnection 等类提供了以编程方式访问 Web 服务的功能。
1.1 InetAddress 类
java.net.InetAddress
此类表示互联网协议 (IP) 地址。IP 地址是 IP 使用的 32 位或 128 位无符号数字,它是一种低级协议,UDP 和 TCP 协议都是在它的基础上构建的。InetAddress 的实例包含 IP 地址,还可能包含相应的主机名(取决于它是否用主机名构造或者是否已执行反向主机名解析)。
1.1.1 创建实例
InetAddress 没有提供构造器,可以使用静态方法获取该实例
方法名 | 说明 |
---|---|
static InetAddress getLocalHost() | 获取本地主机的 InetAddress |
static InetAddress getByName(String host) | 获取指定主机名的 InetAddress |
static InetAddress[] getAllByName(String host) | 获取指定主机名的 InetAddress 组成的数组 |
static InetAddress getByAddress(byte[] addr) | 获取指定 IP 的 InetAddress |
static InetAddress getByAddress(String host, byte[] addr) | 获取指定主机名和 IP 的 InetAddress |
1.1.2 常用方法
方法名 | 说明 |
---|---|
String getCanonicalHostName() | 获取此 IP 地址的完全限定域名 |
String getHostAddress() | 返回 IP 地址字符串 |
String getHostName() | 获取此 IP 地址的主机名 |
boolean isReachable(int timeout) | 测试是否可以达到该地址 |
String toString() | 将此 InetAddress 地址转换为 String |
byte[] getAddress() | 返回此 InetAddress 的原始 IP 地址 |
1.1.3 示例
public class Demo {
public static void main(String[] args) throws Exception {
// 获取 InetAddress 实例
InetAddress localHost = InetAddress.getLocalHost();
byte[] address = localHost.getAddress();
System.out.println("ip-byte:" + Arrays.toString(address));
System.out.println("ip-str:" + localHost.getHostAddress());
}
}
1.2 URL编码
URLDecoder 和 URLEncoder 用于完成普通字符串和 application/x-www-form-urlencoded MIME 字符串之间的相互转换。
1.2.1 application/x-www-form-urlencoded MIME 字符串
在百度搜索框中输入"我爱 Java"
在地址栏中关键字(wd)变成了 “我爱%20Java”
而在 ie 浏览器地址栏中,关键字(wd)变成了 “%E6%88%91%E7%88%B1%20Java”
其实在第一个地址栏中,中文也是被编码的,只是浏览器展示时将其解码了,复制出来依然是编码状态(wd=%E6%88%91%E7%88%B1%20Java)。这些经过编码的字符串就是 application/x-www-form-urlencoded MIME 字符串。
1.2.2 URLDecoder
HTML 格式解码的实用工具类。该类包含了将 String 从 application/x-www-form-urlencoded MIME 格式解码的静态方法。
常用方法
方法名 | 说明 |
---|---|
static String decode(String s) | 已过时 结果字符串可能因平台默认编码不同而不同 |
static String decode(String s, String enc) | 使用指定的编码机制对 application/x-www-form-urlencoded 字符串解码 |
static String decode(String s)
1.2.3 URLEncoder
HTML 格式编码的实用工具类。该类包含了将 String 转换为 application/x-www-form-urlencoded MIME 格式的静态方法。
编码规范
字母数字字符 a
到 z
、A
到 Z
和 0
到 9
保持不变。特殊字符 .
、-
、*
和 _
保持不变。空格字符 " " 转换为一个加号 +
。所有其他字符都是不安全的,因此首先使用一些编码机制将它们转换为一个或多个字节。然后每个字节用一个包含 3 个字符的字符串 “%xy” 表示,其中 xy 为该字节的两位十六进制表示形式。推荐的编码机制是 UTF-8。但是,出于兼容性考虑,如果未指定一种编码,则使用相应平台的默认编码。
空格问题
URL 中关于空格的编码与空格所在位置相关:空格被编码成加号 + 的情况只会在查询字符串部分出现,而被编码成 %20 则可以出现在路径和查询字符串中。
造成这种问题的原因在于:W3C 标准规定,当 Content-Type 为 application/x-www-form-urlencoded 时,URL 中查询参数名和参数值中空格要用加号 + 替代,所以使用该规范的浏览器 URL 查询参数中空格都会被编成加号 +。而在 RFC 2396 中规定, URI 里的保留字符都需转义成 %HH 格式(Section 3.4 Query Component),因此空格会被编码成 %20,加号 + 本身也作为保留字而被编成 %2B,对于某些遵循 RFC 2396 标准的应用来说,它可能不接受查询字符串中出现加号 +,认为它是非法字符。所以一个安全的举措是 URL 中统一使用 %20 来编码空格字符。
Java 中的 URLEncoder 把普通字符串编码成 application/x-www-form-urlencoded MIME 字符串,它的 encode 方法会把空格编码为 +,而 URLDecoder 的 decode 方法会把 + 和 %20 都解码为空格。
常用方法
方法名 | 说明 |
---|---|
static String encode(String s) | 已过时 结果字符串可能因平台默认编码不同而不同 |
static String encode(String s, String enc) | 使用指定的编码机制将字符串转换为 application/x-www-form-urlencoded 格式 |
1.2.4 示例
public class Demo {
public static void main(String[] args) throws Exception {
String encoderStr = URLEncoder.encode("我爱 Java", "UTF-8");
System.out.println("encoder:" + encoderStr);
String decodeStr1 = URLDecoder.decode(encoderStr, "UTF-8");
System.out.println("decoder:" + decodeStr1);
String decodeStr2 = URLDecoder.decode("%E6%88%91%E7%88%B1%20Java", "UTF-8");
System.out.println("decoder:" + decodeStr2);
}
}
1.3 访问 WEB
1.3.1 URL
java.net.URL
代表一个统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。
构造方法
public URL(String spec)
:根据 spec 创建 URL 对象。
public URL(String protocol, String host, int port, String file)
:根据指定 协议、主机名、端口号和文件名创建 URL 对象。
常用方法
方法名 | 说明 |
---|---|
String getAuthority() | 获取此 URL 的授权部分 |
Object getContent() | 获取此 URL 的内容 |
int getDefaultPort() | 获取与此 URL 关联协议的默认端口号 |
String getFile() | 获取此 URL 的文件名 |
String getHost() | 获取此 URL 的主机名 |
String getPath() | 获取此 URL 的路径部分 |
int getPort() | 获取此 URL 的端口号 |
String getProtocol() | 获取此 URL 的协议名称 |
String getQuery() | 获取此 URL 的查询部分 |
URLConnection openConnection() | 返回一个 URLConnection 对象,它表示到 URL 所引用的远程对象的连接 |
InputStream openStream() | 打开到此 URL 的连接并返回一个用于从该连接读入的 InputStream |
1.3.2 URLConnection
java.net.URLConnection
代表应用程序和 URL 之间的通信链接。此类的实例可用于读取和写入此 URL 引用的资源。通常,创建一个到 URL 的连接需要几个步骤:
① 通过在 URL 上调用 openConnection 方法创建连接对象。
② 处理设置参数和一般请求属性。
③ 使用 connect 方法建立到远程对象的实际连接。
④ 远程对象变为可用。远程对象的头字段和内容变为可访问。
构造方法
protected URLConnection(URL url)
:构造一个到指定 URL 的 URL 连接。
常用方法
方法名 | 说明 |
---|---|
abstract void connect() | 打开到此 URL 引用的资源的通信链接 |
Object getContent() | 获取此 URL 连接的内容 |
URL getURL() | 返回此 URLConnection 的 URL 字段的值 |
InputStream getInputStream() | 返回从此打开的连接读取的输入流 |
OutputStream getOutputStream() | 返回写入到此连接的输出流 |
void setConnectTimeout(int timeout) | 设置一个指定的超时值(以毫秒为单位) |
int getConnectTimeout() | 返回连接超时设置 |
1.3.3 示例
public class Demo {
public static void main(String[] args) throws Exception {
// 创建 URL
URL url = new URL("http://ip-api.com/json/47.103.4.205");
// 获取 URLConnection 对象
URLConnection urlConnection = url.openConnection();
// 打开链接
urlConnection.connect();
// 将从 URLConnection 获取的输入流放入缓冲流
BufferedReader in = new BufferedReader(
new InputStreamReader(urlConnection.getInputStream(), "UTF-8"));
// 将返回值追加到 result
String result = "";
String getLine;
while ((getLine = in.readLine()) != null) {
result += getLine;
}
// 释放资源
in.close();
// 输出返回值
System.err.println(result);
}
}