dcLunatic's blog

Java网络编程

字数统计: 8.4k阅读时长: 35 min
2018/09/21 Share

网络编程

InetAddress

简述

java中使用InetAddress类来表示ip地址,其两个子类Inet4Address和Inet6Address分别表示ipv4地址和ipv6地址。

没有明显的构造函数,通过静态方法获得实例

方法

  • public static InetAddress getByName(String host) throws UnknownHostException

    在给定的主机名的情况下确定主机的ip地址。当找不到host的ip地址或者scope_id为全局的ipv6地址指定的,则抛出异常。

    主机名可以是机器名(如 “java.sun.com“),也可以是其 IP 地址的文本表示形式。如果提供字面值 IP 地址,则仅检查地址格式的有效性。

  • public static InetAddress[] getAllByName(String host) throws UnknownHostException

    在给定主机名的情况下,根据系统上配置的名称服务返回其ip地址所组成的数组。当找不到host的ip地址或者scope_id为全局的ipv6地址指定的,则抛出异常。

    主机名可以是机器名(如 “java.sun.com“),也可以是其 IP 地址的文本表示形式。如果提供字面值 IP 地址,则仅检查地址格式的有效性。

  • public static InetAddress getByAddress(byte[] addr) throws UnknownHostException

    在给定原始ip地址的情况下,返回InetAddress对象。参照网络字节顺序,地址高位字节位于getAddress()[0]中。ipv4地址byte数组的长度必须为4个字节,ipv6的必须为16个字节。如果长度非法,则抛出异常。

  • public static InetAddress getByAddress(String host, byte[] addr) throws UnknownHostException

    根据提供的主机名和IP地址创建InetAddress。不检查名称服务的地址有效性。当ip地址长度非法时,抛出异常。

    主机名可以是机器名(如 “java.sun.com“),也可以是其 IP 地址的文本表示形式。

  • public static InetAddress getLocalHost() throws UnknownHostException

    返回本地主机的ip地址。如果找不到host的任何ip地址的时候,抛出异常。

下面是一些常用的方法

  • public byte[] getAddress() //返回此对象的原始ip地址,结果按照网络字节顺序。
  • public String getHostAddress() //以字符串形式返回ip地址。
  • public String getHostName() //以字符串形式返回主机名。如果此 InetAddress 是用主机名创建的,则记忆并返回主机名;否则,将执行反向名称查找并基于系统配置的名称查找服务返回结果。
  • public String toString() //将此ip地址转换为主机名/字面值ip地址形式的字符串。如果主机名未解析,则主机名为空。
  • public boolean isReachable(int timeout) throws IOException //测试是否可以达到该地址。超时值单位为毫秒。发生网络异常时,抛出IOException,timeout为负时抛出IllegalArgumentException。
  • public boolean isReachable(NetworkInterface netif, int ttl, int timeout) //测试是否可以到达该地址。允许指定网络接口和数据包的最大跳数,超时值单位为毫秒。发生网络异常时,抛出IOException,ttl或timeout为负时抛出IllegalArgumentException。
  • public String getCanonicalHostName() //获取此ip地址的完全限定域名。

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.net.InetAddress;
public class InetAddressTest{
public static void main(String... args) throws Exception{
InetAddress addr = InetAddress.getByName("183.232.231.172");
System.out.println(addr);
addr = InetAddress.getByName("www.baidu.com");
System.out.println(addr);
System.out.println("完全限定域名: " + addr.getCanonicalHostName());
byte[] ipaddr = new byte[4];
int index = 0;
for(int i : new int[]{183,232,231,172})
ipaddr[index++] = (byte)(i&0xff);
addr = InetAddress.getByAddress(ipaddr);
System.out.println(addr);

System.out.println("是否可达: " + addr.isReachable(1000));
}
}

URL

URL对象代表统一资源定位符,是指向互联网资源的指针,它使用协议名、主机名、端口和资源组成,即满足如下格式:protocol://host:port/resourceName,可以通过URL对象来获取该URL对应的资源等信息。

但URL 类自身并不根据 RFC2396 中定义的转义机制编码或解码任何 URL 部分。由调用方对任何需要在调用 URL 前进行转义的字段进行编码,并对从 URL 返回的任何经过转义的字段进行解码。比如对于这两个URL:http://foo.com/hello world/http://foo.com/hello%20world将被视为互不相等。

注意,URI 类在某些特定情况下对其组成字段执行转义。建议使用 URI 管理 URL 的编码和解码,并使用 toURI() 和 URI.toURL() 实现这两个类之间的转换。

也可以使用 URLEncoder 和 URLDecoder 类,但是只适用于 HTML 形式的编码,它与 RFC2396 中定义的编码机制不同。

常用构造方法

  • public URL(String spec) throws MalformedURLException //根据String表示形式创建URL对象,当协议不存在或者未知时,抛出异常。
  • **URL(String protocol, String host, int port, String file) throws MalformedURLException ** //根据protocol、host、port、file创建URL对象,当port为-1时,使用协议的默认端口。当协议不存在或者未知时,抛出异常。
  • URL(String protocol, String host, String file) throws MalformedURLException //根据protocol、host、file创建URL对象,这里使用的是协议的默认端口。当协议不存在或者未知时,抛出异常。
  • URL(URL context, String url) throws MalformedURLException //使用基地址和相对位置创建URL对象。当协议不存在或者未知时,抛出异常。

常用方法

  • public String getAuthority() //获得此URL的授权部分。
  • public Object getContent() //获得此URL的内容。
  • public Object getContent(Class[] classes) //获得此URL的内容,相当于openConnection().getContent(Class[])。
  • public int getDefaultPort() //返回此URL关联协议的默认端口号。
  • public String getFile() //返回此URL的文件名
  • public String getHost() //返回此URL的主机名
  • public String getPath() //返回此URL的路径部分
  • public int getPort() //返回此URL的端口号
  • public String getProtocol() //返回此URL的协议名称
  • public String getQuery() //返回此URL的查询部分
  • public String getRef() //返回此URL的锚点(也称引用)
  • public URLConnection openConnection() //返回一个URLConnection对象,表示URL所引用的远程对象的连接
  • public URLConnection openConnection(Proxy proxy) //与 openConnection() 类似,所不同是连接通过指定的代理建立;不支持代理方式的协议处理程序将忽略该代理参数并建立正常的连接。
  • public InputStream openStream() //打开到此URL的连接并返回一个用于从该连接接入的InputStream
  • public boolean sameFile(URL other) //比较两个URL,不包括片段部分
  • public String toExternalForm() //返回此URL的字符串形式,作用跟toString()一样
  • public URI toURI() //返回与此URL等效的URI。

使用例子

下载一张图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.net.URL;
import java.io.InputStream;
import java.io.FileOutputStream;
import java.io.File;
public class URLTest{
public static void main(String... args) throws Exception{
URL imgurl = new URL("http://img5.duitang.com/uploads/item/201511/06/20151106190951_YXSZN.jpeg");
System.out.println("路径部分:" + imgurl.getPath());
System.out.println("文件名:" + imgurl.getFile());
InputStream is = imgurl.openStream();
File file = new File("picture.jpg");
if(!file.exists())
file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
int ch;
while((ch = is.read()) != -1)
fos.write(ch);
fos.close();
is.close();
System.out.println("Done.");
}
}

另外一个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
//通过命令行参数指定在斗图啦网站要搜索的图片的关键字,然后将搜索结果的前几张图片下载保存
import java.net.*;
import java.io.*;
import java.util.regex.*;
import java.util.*;
public class MyPictureTool{
private static final String DTL = "http://www.doutula.com";
//给出目的地址,测试在指定时间内是否能到达地址所在的主机
private static boolean testNetwork(String str, int timeout){
try{
URL url = new URL(str);
InetAddress addr = InetAddress.getByName(url.getHost());
if(addr.isReachable(timeout))
return true;
else return false;
}catch(Exception e){
return false;
}
}
//获取斗图啦的搜索结果
private static String search(String key){
try{
String searchUrl = DTL + "/search?keyword=" + URLEncoder.encode(key, "UTF-8");
//System.out.println(searchUrl);
URL url = new URL(searchUrl);
InputStream is = url.openStream();
BufferedReader bf = new BufferedReader(new InputStreamReader(is));
StringBuilder content = new StringBuilder();
String line;
while((line = bf.readLine()) != null){
content.append(line);
content.append("\n");
}
bf.close();
return content.toString();
}catch(Exception e){
return null;
}
}
//写入内容到指定文件
private static boolean writeToFile(String data, String filename, boolean flag){
try{
File file = new File(filename);
if(!file.exists())
file.createNewFile();
FileWriter fw = new FileWriter(file, flag);
fw.write(data);
fw.close();
return true;
}catch(Exception e){
e.printStackTrace();
return false;
}
}
//将链接对应的URL资源下载保存到指定的文件中
private static boolean downloadUrl(String strUrl, String filename){
try{
File file = new File(filename);
if(!file.exists())
file.createNewFile();
URL url = new URL(strUrl);
InputStream is = url.openStream();
FileOutputStream fos = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len = -1;
while((len = is.read(buf)) != -1){
fos.write(buf, 0, len);
}
fos.close();
is.close();
return true;

}catch(Exception e){
return false;
}
}
//匹配搜索结果中的图片链接,并保存在list参数中,可指定返回的链接数,返回实际返回的链接数
private static int getPictureUrl(String html, List<String> list, int count){
try{
Matcher matcher = Pattern.compile("<div class=\"random_picture\">[\\s\\S]*?(?<!</script>)\n</div>").matcher(html);
if(matcher.find()){
String rs = matcher.group();
matcher = Pattern.compile("<img.*?data-backup=\"(.*?)\"").matcher(rs);
int i;
for(i = 0; i < count && matcher.find(); i++){
list.add(matcher.group(1).replace("thumb150", "large"));
}
return i;
}
else
return 0;
}catch(Exception e){
return -1;
}

}
//获取pictureUrl的图片类型,如"jpg" "gif"等
private static String getPictureType(String pictureUrl){
int pos = pictureUrl.lastIndexOf('.');
if(pos == -1)
return null;
return pictureUrl.substring(pos+1, pictureUrl.length());
}
public static void main(String[] args) throws Exception{
if(args.length != 2 && args.length != 1){
System.out.println("从斗图啦网站搜索并下载指定数量的关键词相关图片");
System.out.println("Usage: java MyPictureTool keyWord [downloadCount=6]");
System.exit(-1);
}
int count = 0;
if(args.length == 1)
count = 6;
if(args.length == 2){
try{
count = Integer.parseInt(args[1]);
if(count < 1){
System.out.println("请输入正确的downloadCount参数");
System.out.println("从斗图啦网站搜索并下载指定数量的关键词相关图片");
System.out.println("Usage: java MyPictureTool keyWord [downloadCount=6]");
System.exit(-1);
}
}catch(Exception e){
System.out.println("请输入正确的downloadCount参数");
System.out.println("从斗图啦网站搜索并下载指定数量的关键词相关图片");
System.out.println("Usage: java MyPictureTool keyWord [downloadCount=6]");
System.exit(-1);
}
}
System.out.println(">> 搜索关键词为 " + args[0] + " 的图片,并下载搜索结果的前 " + count + " 张\n");
String html = search(args[0]);
List<String> pictureUrl = new ArrayList<String>(count);
if(getPictureUrl(html, pictureUrl, count) < 1){
System.out.println("搜索结果异常");
System.exit(-2);
}

//创建下载文件目录
File downloadDir = new File("." + File.separator + args[0]);
if(!downloadDir.exists())
downloadDir.mkdirs();


int successDownload = 0;
for(int i = 0; i < pictureUrl.size(); i++){
System.out.println("图片链接: " + pictureUrl.get(i));
String type = getPictureType(pictureUrl.get(i));
if(type == null){
System.out.println("链接异常,跳过");
continue;
}
String pictureName = "." + File.separator + args[0] + File.separator + (i+1) + "." + type;
System.out.println("正在保存图片...");
if(downloadUrl(pictureUrl.get(i), pictureName)){
System.out.println("保存成功,图片位置: " + pictureName);
successDownload++;
}
else
System.out.println("由于异常原因,保存失败");
}
System.out.println("\n>> 下载完成,成功下载 " + successDownload + " 张");
System.out.println("Done.");

}
}

URI(此部分来自api文档)

URI 语法和组成部分

在最高级别上,字符串形式的 URI 引用(以下简写为”URI”)语法如下

[scheme:]scheme-specific-part[**#**fragment]

其中,方括号 […] 用于描述可选组成部分,字符 **:**和 **#**代表它们自身。

绝对 URI 指定了方案(scheme);非绝对的 URI 称为相对URI。URI 还可以根据其是否为不透明的分层的 进行分类。

不透明 URI 为绝对 URI,其特定于方案的部分不是以斜线字符 (‘/‘) 开始。不透明 URI 无法进行进一步解析。下面是不透明 URI 的一些示例:

mailto:java-net@java.sun.com
news:comp.lang.java
urn:isbn:096139210x

分层 URI 或者为绝对 URI(其特定于方案的部分以斜线字符开始),或者为相对 URI,即不指定方案的 URI。下面是分层 URI 的一些示例:

http://java.sun.com/j2se/1.3/
docs/guide/collections/designfaq.html#28
http://www.cnblogs.com/../demo/jfc/SwingSet2/src/SwingSet2.java
file:///~/calendar

分层 URI 还要按照下面的语法进行进一步的解析

[scheme:][**//authority][path][?query][#**fragment]

其中,**:/?**和 **#**代表它们自身。分层 URI 的特定于方案的部分包含方案和片段部分之间的字符。

分层 URI 的授权组成部分(如果指定)为基于服务器的基于注册表的。基于服务器的授权按照如下众所周知的语法进行解析:

[user-info@]host[**:**port]

其中,字符 **@**和 **:**代表它们自身。几乎当前使用的所有 URI 方案都是基于服务器的。不能采用这种方式解析的授权组成部分被视为基于注册表的。

如果分层 URI 的路径组成部分以斜线字符 (‘/‘) 开始,则称此 URI 本身为绝对的;否则它为相对的。分层 URI 或者为绝对的,或者指定了授权的路径,它始终为绝对的。

如上所述,URI 实例具有以下九个组成部分:

组成部分 类型
方案 String
特定于方案的部分 String
授权 String
用户信息 String
主机 String
端口 int
路径 String
查询 String
片段 String

在给定实例中,任何特殊组成部分都或者为未定义的,或者为已定义的,并且有不同的值。未定义的字符串组成部分由 null 表示,未定义的整数组成部分由 -1 表示。已定义的字符串组成部分的值可以为空字符串;这与未定义的组成部分不等效。

实例中特定的组成部分是已定义的还是未定义的取决于所代表的 URI 类型。绝对 URI 具有方案组成部分。不透明的 URI 具有一个方案、一个特定于方案的部分,以及可能会有一个片段,但是没有其他组成部分。分层 URI 总是有一个路径(尽管可能为空)和一个特定于方案的部分(它至少包含一个路径),还可以包含任何其他组成部分。如果有授权组成部分且它又是基于服务器的,则主机组成部分将被定义,也有可能定义用户信息和端口组成部分。

URI分类

绝对URI和相对URI

绝对URI:以scheme组件起始的完整格式,如http://fsjohnhuang.cnblogs.com。表示以对标识出现的环境无依赖的方式引用资源。
相对URI:不以scheme组件起始的非完整格式,如fsjohnhuang.cnblogs.com。表示以对依赖标识出现的环境有依赖的方式引用资源。

不透明URI和分层URI

不透明URI:scheme-specific-part组件不是以正斜杠(/)起始的,如mailto:fsjohnhuang@xxx.com。由于不透明URI无需进行分解操作,因此不会对scheme-specific-part组件进行有效性验证。

分层URI:scheme-specific-part组件是以正斜杠(/)起始的,如http://fsjohnhuang.com。

针对 URI 实例的运算

此类支持的主要运算有规范化解析相对化 运算。

规范化 是将分层 URI 的路径组成部分中的不必要的”.” 和 “..” 部分移除的过程。每个 “.” 部分都将被移除。”..” 部分也被移除,除非它前面有一个非 “..” 部分。规范化对不透明 URI 不产生任何效果。

解析 是根据另一个基本 URI 解析某个 URI 的过程。得到的 URI 由两个 URI 组成部分构造,构造方式由 RFC 2396 指定,从基本 URI 取出原始 URI 中未指定的组成部分。对于分层 URI,原始的路径根据基本路径进行解析,然后进行规范化。例如,解析以下 URI

docs/guide/collections/designfaq.html#28 (1)

根据基本 URI http://java.sun.com/j2se/1.3/ 解析,结果为 URI

http://java.sun.com/j2se/1.3/docs/guide/collections/designfaq.html#28

解析相对 URI

http://www.cnblogs.com/../demo/jfc/SwingSet2/src/SwingSet2.java (2)

根据此结果应生成

http://java.sun.com/j2se/1.3/demo/jfc/SwingSet2/src/SwingSet2.java

支持对绝对和相对 URI,以及分层 URI 的绝对和相对路径的解析。根据任何其他 URI 对 URI file:///~calendar 进行解析只能生成原始的 URI,因为它是绝对路径。根据相对基础 URI (1) 解析相对 URI (2) 将生成规范的但依然是相对的 URI

demo/jfc/SwingSet2/src/SwingSet2.java

最后,相对化 是解析的逆过程:对于任何两个规范的 URI uv

u.relativize(u.resolve(v)).equals(v)和
u.resolve(u.relativize(v)).equals(v)。

此运算在下面的场合非常有用:构造一个包含 URI 的文档,该URI 必须尽可能是根据文档的基本 URI 建立的相对 URI。例如,相对化 URI

http://java.sun.com/j2se/1.3/docs/guide/index.html

根据基本 URI

http://java.sun.com/j2se/1.3

生成了相对 URI docs/guide/index.html。

字符分类

RFC 2396 精确指出 URI 引用中的各个不同组成部分允许使用的字符。以下分类大部分取自该规范,这些约束的用法描述如下:

alpha US-ASCII 字母字符,’A’ 到 ‘Z’ 以及 ‘a’ 到 ‘z’
digit US-ASCII 十进制数字符,’0’ 到 ‘9’
alphanum 所有 alphadigit字符
unreserved 所有 alphanum字符及字符串 “_-!.~’()*” 中包含的字符
punct 字符串 “,;:$&+=” 中包含的字符
reserved 所有 punct字符及字符串 “?/[]@” 中包含的字符
escaped 转义八位组,即三部分组合:百分号 (‘%’) 后跟两个十六进制数(’0’-‘9’、’A’-‘F’ 和 ‘a’-‘f’)
other 未包含在 US-ASCII 字符集中的 Unicode 字符不是控制字符(根据 Character.isISOControl 方法),并且不是空格字符(根据 Character.isSpaceChar 方法)*(*与 RFC 2396 有些出入**,RFC 2396 限制为 US-ASCII)

全部合法 URI 字符集包含 unreservedreservedescapedother字符。

转义八位组、引用、编码和解码

RFC 2396 允许用户信息、路径、查询和片段组成部分中包含转义八位组。转义在 URI 中实现两个目的:

  • 当要求 URI 不能包含任何 other 字符以严格遵守 RFC 2396 时,需要对非 US-ASCII 字符进行编码
  • 引用 组成部分中的非法字符。用户信息、路径、查询和片段组成部分在判断哪些字符合法哪些字符非法上稍有不同。

在此类中由三个相关的运算实现了这两个目的:

  • 字符的编码 方式是,用代表该字符在 UTF-8 字符集中的字符的转义八位组序列取代该字符。例如,欧元符号 (‘\u20AC’) 编码后为 “%E2%82%AC”。*(*与 RFC 2396 有些出入**,RFC 2396 未指定任何特殊字符集)
  • 非法字符通过简单地对它进行编码来引用。例如,空格字符,用 “%20” 取代它来进行引用。UTF-8 包含 US-ASCII,因此对于 US-ASCII 字符,此转换具有的效果与 RFC 2396 的要求相同。
  • 对转义八位组序列进行解码 的方法是,用它所代表的 UTF-8 字符集中的字符的序列将它取代。UTF-8 包含 US-ASCII,因此解码具有对引用的任何 US-ASCII 字符取消引用的效果,以及对任何编码的非 US-ASCII 字符进行解码的效果。如果在对转义八位组进行解码时出现解码错误,则出错的八位组用 Unicode 替换字符 ‘\uFFFD’ 取代。

这些运算在此类的构造方法和方法中公开,如下所示:

  • 单参数构造方法要求对参数中的任何非法字符都必须引用,并保留出现的任何转义八位组和 other字符。
  • 多参数构造方法根据其中出现的组成部分的需要对非法字符进行引用。百分号字符 (‘%’) 始终通过这些构造方法引用。任何 other字符都将被保留。
  • getRawUserInfogetRawPathgetRawQuerygetRawFragmentgetRawAuthoritygetRawSchemeSpecificPart 方法以原始形式返回它们的相应组成部分的值,不解释任何转义八位组。由这些方法返回的字符串有可能包含转义八位组和 other字符,但不包含任何非法字符。
  • getUserInfogetPathgetQuerygetFragmentgetAuthoritygetSchemeSpecificPart 方法解码相应的组成部分中的任何转义八位组。由这些方法返回的字符串有可能包含 other字符和非法字符,但不包含任何转义八位组。
  • toString 返回带所有必要引用的 URI 字符串,但它可能包含 other 字符。
  • toASCIIString 方法返回不包含任何 other字符的、完全引用的和经过编码的 URI 字符串。

标识

对于任何 URI u,下面的标识有效

new URI(u.toString()).equals(u) .

对于不包含冗余语法的任何 URI u,比如在一个空授权前面有两根斜线(如 file:///tmp/)和主机名后面跟一个冒号但没有端口(如http://java.sun.com:),以及除必须引用的字符之外不对字符编码的情况,下面的标识也有效:

new URI(u.getScheme()、
u.getSchemeSpecificPart()、
u.getFragment())
.equals(u)

在所有情况下,以下标识有效

new URI(u.getScheme()、
u.getUserInfo()、 u.getAuthority()、
u.getPath()、 u.getQuery()、
u.getFragment())
.equals(u)

如果 u为分层的,则以下标识有效

new URI(u.getScheme()、
u.getUserInfo()、 u.getHost()、 u.getPort()、
u.getPath()、 u.getQuery()、
u.getFragment())
.equals(u)

如果 u为分层的并且没有授权或没有基于服务器的授权。

URI、URL和 URN

URI 是统一资源标识符,而 URL 是统一资源定位符。因此,笼统地说,每个 URL 都是 URI,但不一定每个 URI 都是URL。这是因为 URI 还包括一个子类,即统一资源名称 (URN),它命名资源但不指定如何定位资源。上面的 mailto、news 和 isbn URI 都是URN 的示例。

URI 和 URL 概念上的不同反映在此类和 URL 类的不同中。

此类的实例代表由 RFC 2396 定义的语法意义上的一个 URI 引用。URI 可以是绝对的,也可以是相对的。对 URI 字符串按照一般语法进行解析,不考虑它所指定的方案(如果有)不对主机(如果有)执行查找,也不构造依赖于方案的流处理程序。相等性、哈希计算以及比较都严格地根据实例的字符内容进行定义。换句话说,一个 URI 实例和一个支持语法意义上的、依赖于方案的比较、规范化、解析和相对化计算的结构化字符串差不多。

作为对照,URL 类的实例代表了 URL 的语法组成部分以及访问它描述的资源所需的信息。URL 必须是绝对的,即它必须始终指定一个方案。URL 字符串按照其方案进行解析。通常会为 URL 建立一个流处理程序,实际上无法为未提供处理程序的方案创建一个 URL 实例。相等性和哈希计算依赖于方案和主机的 Internet 地址(如果有);没有定义比较。换句话说,URL 是一个结构化字符串,它支持解析的语法运算以及查找主机和打开到指定资源的连接之类的网络 I/O 操作。

构造方法

  • public URI(String str) throws URISynataxException //通过给定的字符串构造一个URI

    如果给定字符串违背 RFC 2396,抛出异常。

  • public URI(String scheme, String ssp, String fragment) throws URISynataxException //根据给定的组成部分构造一个URI

    如果给定字符串违背 RFC 2396,抛出异常。

  • public URI(String scheme, String userInfo, String host, int port, String path, String query, String fragment) throws URISynataxException //通过给定组成部分构造一个分层URI

    如果方案和路径都已给出但路径为相对的,如果从给定组成部分构造的 URI 字符串违背 RFC 2396,或者如果字符串的授权组成部分存在但无法解析为基于服务器的授权,抛出异常

  • public URI(String scheme, String host, String path, String fragment) throws URISynataxException //给据给定组成部分构造一个分层URI

    如果给定字符串违背 RFC 2396,抛出异常。

  • public URI(String scheme, String authority, String path, String query, String fragment) throws URISynataxException //根据给定组成部分构造一个分层URI

    如果方案和路径都已给出但路径为相对的,如果从给定组成部分构造的 URI 字符串违背 RFC 2396,或者如果字符串的授权组成部分存在但无法解析为基于服务器的授权,抛出异常

常用方法

  • public int compareTo(URI uri) //将此URI和uri进行比较

  • public static URI create(String str) //通过给定的字符串构建一个URI

  • public String getAutority()

  • public Sring getFragment()

  • public String getHost()

  • public String getPath()

  • public String getPort()

  • public String getQuery()

  • public String getUserInfo()

  • public String getScheme()

    返回此URI的组成部分

  • public boolean isAbsolute() //此URI是否为绝对的

  • public boolean isOpaque() //此URI是否为不透明的

  • public URI normalize() //规范化此URI的路径

  • public URI relativize(URI uri) //根据此URI将给定URI规范化

  • public URI resolve(String str) //解析给定的字符串,然后在此URI的基础上构造一个新的URI

  • public URI resolve(URI uri) //根据此URL解析给定的uri

  • public String toASCIIString() //以US-ASCII字符串形式返回此URI的内容

  • public URL toURL() //根据此URI构造一个URL,如果该URI不是绝对的

例子

  1. 输出URI的组成部分信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.net.*;
public class URITest1{
public static void main(string[] args) throws Exception{
if(args.length != 1){
System.out.println("Usage: java URITest1 uri");
System.exit(-1);
}
URI uri = new URI(args[0]);
System.out.println ("Authority = " +uri.getAuthority ());
System.out.println ("Fragment = " +uri.getFragment ());
System.out.println ("Host = " +uri.getHost ());
System.out.println ("Path = " +uri.getPath ());
System.out.println ("Port = " +uri.getPort ());
System.out.println ("Query = " +uri.getQuery ());
System.out.println ("Scheme = " +uri.getScheme ());
System.out.println ("Scheme-specific part = " + uri.getSchemeSpecificPart ());
System.out.println ("User Info = " +uri.getUserInfo ());
System.out.println ("URI is absolute: " +uri.isAbsolute ());
System.out.println ("URI is opaque: " +uri.isOpaque ());
System.out.println ("Normalized URI = " + uri.normalize());
}
}

运行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
root@dcLunatic:~/Desktop/JavaTest/net# java URITest1 http://www.baidu.com/index.php#banner
Authority = www.baidu.com
Fragment = banner
Host = www.baidu.com
Path = /index.php
Port = -1
Query = null
Scheme = http
Scheme-specific part = //www.baidu.com/index.php
User Info = null
URI is absolute: true
URI is opaque: false
Normalized URI = http://www.baidu.com/index.php#banner
  1. 规范化解析
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import java.net.*;
public class URITest2{
public static void main(string[] args) throws Exception{
if(args.length != 2){
System.out.println("Usage: java URITest2 uriBase uriRelative");
System.exit(-1);
}
URI uriBase = new URI (args [0]);
System.out.println ("Base URI = " +uriBase);

URI uriRelative = new URI (args [1]);
System.out.println ("Relative URI = " +uriRelative);

URI uriResolved = uriBase.resolve (uriRelative);
System.out.println ("Resolved URI = " +uriResolved);

URI uriRelativized = uriBase.relativize (uriResolved);
System.out.println ("Relativized URI = " +uriRelativized);
}
}

运行结果:

1
2
3
4
5
root@dcLunatic:~/Desktop/JavaTest/net# java URITest2 http://www.baidu.com/index.php index.php/../login.php
Base URI = http://www.baidu.com/index.php
Relative URI = index.php/../login.php
Resolved URI = http://www.baidu.com/login.php
Relativized URI = http://www.baidu.com/login.php

URLDecoder

简述

HTML 格式解码的实用工具类。该类包含了将 String 从 application/x-www-form-urlencoded MIME 格式解码的静态方法。

该转换过程正好与 URLEncoder 类使用的过程相反。假定已编码的字符串中的所有字符为下列之一:”a” 到 “z”、”A” 到 “Z”、”0” 到 “9” 和 “-“、”_”、”.” 以及 “*”。允许有 “%” 字符,但是将它解释为特殊转义序列的开始。

转换中使用以下规则:

字母数字字符 "a" 到 "z"、"A" 到 "Z" 和 "0" 到 "9" 保持不变。
特殊字符 "."、"-"、"*" 和 "_" 保持不变。
加号 "+" 转换为空格字符 " "。
将把 "%xy" 格式序列视为一个字节,其中 xy 为 8 位的两位十六进制表示形式。然后,所有连续包含一个或多个这些字节序列的子字符串,将被其编码可生成这些连续字节的字符所代替。可以指定对这些字符进行解码的编码机制,或者如果未指定的话,则使用平台的默认编码机制。

该解码器处理非法字符串有两种可能的方法。一种方法是不管该非法字符,另一种方法是抛出 IllegalArgumentException 异常。解码器具体采用哪种方法取决于实现。

构造方法

  • public URLDecoder() //创建一个URLDecoder

方法

  • public static String decode(String s) //已过时,将字符串s解码,但是结果会因为平台的默认编码不同而产生不同的结果

  • public static String decode(String s, String enc) throws UnsupportedEncodingException //使用指定的编码机制对application/x-www-form-urlencoded 字符串进行解码。一般都是使用UTF-8,如果使用其他编码,可能会造成不兼容性。

    当指定的字符编码不被支持时,抛出异常。

URLEncoder

简述

该类作用与URLDecoder相反。不解释

构造方法

  • public URLEncoder() //创建一个URLEncoder

方法

  • public static String encode(String s) //已过时,将字符串s编码,但是结果会因为平台的默认编码不同而产生不同的结果
  • public static String encode(String s, String enc) throws UnsupportedEncodingException //使用指定的编码机制将字符串编码成application/x-www-form-urlencoded 格式。一般应使用 UTF-8。如果不使用该编码,可能造成不兼容性。

URLConnection

简述

首先,这是一个抽象类,是所有URL连接类的超类,它代表应用程序和URL之间的通信连接。此类实例可用于读取和写入此URL引用的资源。

通常,创建一个到URL的连接需要以下的步骤:

  1. 通过在URL上调用openConnnection方法创建连接对象
  2. 处理设置参数和一般请求属性
  3. 使用connect方法建立到远程对象的连接
  4. 远程对象变为可用。远程对象的头字段和内容变为可访问。

一般情况下,所有的预连接参数和一般请求属性都可忽略,这些一般都默认为敏感值,比较常用的两个方法getInputStream和getContent。

字段

  • protected boolean allowUserInteraction //如果为 true,则在允许用户交互(例如弹出一个验证对话框)的上下文中对此 URL 进行检查。
  • protected boolean connnected //如果为 false,则此连接对象尚未创建到指定 URL 的通信链接。
  • protected boolean doInput //此变量由setDoInput方法设置
  • protected boolean doOutput //此变量由setDoOutput方法设置
  • protected long ifModifiedSince //有些协议支持跳过对象获取,除非该对象在某个特定时间点之后又进行了修改。
  • protected URL url //URL 表示此连接要在互联网上打开的远程对象。
  • protected boolean useCaches //如果为true,则只要有条件就允许协议使用缓存。

构造方法

  • protected URLConnnection(URL url) //创建一个到指定URL的URL连接

常用方法

  1. 与字段相关的方法
  • public static boolean getDefaultAllowUserInteraction() //返回URLConnection对象默认的allowUserInteraction字段的值

  • public static void setDefaultAllowUserInteraction(boolean defaultallowuserinteraction)

                                                                                                                   //将未来的所有 URLConnection 对象的 allowUserInteraction 字段的默认值设置为指定的值
    
  • public boolean getAllowUserInteraction() //返回此对象的allowUserInteraction字段的值

  • public void setAllowUserInteraction(boolean allowuserinteraction)

    ​ //设置此 URLConnection 的 allowUserInteraction 字段的值

  • public boolean getDefaultUseCaches() //返回此对象默认的useCaches字段的值

  • public void setDefaultUseCaches(boolean defaultusecaches)//将 useCaches 字段的默认值设置为指定的值

  • public boolean getUseCaches() //返回此对象的useCaches字段的值

  • public void setUseCaches(boolean usecaches) //将此 URLConnection 的 useCaches 字段的值设置为指定的值

  • public boolean getDoInput() //返回此对象的doInput字段的值

  • public void setDoInput(boolean doinput) //将此 URLConnection 的 doInput 字段的值设置为指定的值

  • public boolean getDoOutput() //返回此对象的doOutput字段的值

  • public void setDoOutput(boolean dooutput) //将此 URLConnection 的 doOutput 字段的值设置为指定的值

  • public long getIfModifiedSince() //返回此对象的ifModifiedSince字段的值

  • public void setIfModifiedSince(long ifmodifiedsince) //将此对象的 ifModifiedSince 字段的值设置为指定的值

  • public URL getURL() //返回此对象的url字段的值

  1. 与响应头字段相关的方法
  • public String getContentEncoding() //返回content-encoding头字段的值
  • public int getContentLength() //返回content-length头字段的值
  • public String getContentType() //返回content-type头字段的值
  • public long getExpiration() //返回expires头字段的值
  • public long getDate() //返回date头字段的值
  • public String getHeaderField(int n) //返回第n个头字段的值
  • public String getHeaderField(String name) //返回指定的头字段的值
  • public String getHeaderFieldKey(String key) //返回第n个头字段的键
  • public Map<String, List> getHeaderFields() //返回头字段的map(不可修改)
  • public long getLastModified() //返回last-modified头字段的值
  1. 与请求属性相关的方法
  • public void addRequestProperty(String key, String value) //添加由键值对指定的一般请求属性
  • public String getRequestProperty(String key) //返回此连接指定的一般请求属性值
  • public void setRequestProperty(String key, String value) //设置一般请求属性
  • public Map<String, List> getRequestProperties() //返回此连接的一般请求属性的map(不可修改)
  1. 与连接设置有关的方法
  • public abstract void connect() //打开到此URL引用的资源的通信链接,如果尚未连接的话
  • public int getConnectTimerout() //返回此连接超时设置
  • public void setConnectTimeout(int timeout) //将一个指定的超时值(以毫秒为单位),该值将在打开到此 URLConnection 引用的资源的通信链接时使用
  • public int getReadTimeout() //返回读入超时设置
  • public void setReadTimeout(int timeout) //将读超时设置为指定的超时值,以毫秒为单位
  1. 在连接后读写内容相关的方法
  • public Object getContent() //获取此URL连接的内容
  • public Object getContent(Class[] classes) //获取此URL连接的内容
  • public InputStream getInputStream() //返回从此打开的连接读取的输入流
  • public OutputStream getOutputStream() //返回到此连接的输出流
  1. 其他方法
  • public static String guessContentTypeFromName(String fname)//根据url的指定的file部分尝试确定对象的内容类型
  • public static String guessContentTypeFromStream(InputStream is)//根据输入流的开始字符尝试确定输入流的类型
  • public String toString() //返回此 URL 连接的 String 表示形式

例子

1

原文作者:dcLunatic

原文链接:http://dclunatic.github.io/Java%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B.html

发表日期:September 21st 2018, 1:50:54 pm

更新日期:July 11th 2021, 9:13:50 pm

版权声明:转载的时候,记得注明来处

CATALOG
  1. 1. 网络编程
    1. 1.1. InetAddress
      1. 1.1.1. 简述
      2. 1.1.2. 方法
      3. 1.1.3. 例子
    2. 1.2. URL
      1. 1.2.1. 常用构造方法
      2. 1.2.2. 常用方法
      3. 1.2.3. 使用例子
    3. 1.3. URI(此部分来自api文档)
      1. 1.3.1. URI 语法和组成部分
      2. 1.3.2. URI分类
        1. 1.3.2.1. 绝对URI和相对URI
        2. 1.3.2.2. 不透明URI和分层URI
      3. 1.3.3. 针对 URI 实例的运算
      4. 1.3.4. 字符分类
      5. 1.3.5. 转义八位组、引用、编码和解码
      6. 1.3.6. 标识
      7. 1.3.7. URI、URL和 URN
      8. 1.3.8. 构造方法
      9. 1.3.9. 常用方法
      10. 1.3.10. 例子
    4. 1.4. URLDecoder
      1. 1.4.1. 简述
      2. 1.4.2. 构造方法
      3. 1.4.3. 方法
    5. 1.5. URLEncoder
      1. 1.5.1. 简述
      2. 1.5.2. 构造方法
      3. 1.5.3. 方法
    6. 1.6. URLConnection
      1. 1.6.1. 简述
      2. 1.6.2. 字段
      3. 1.6.3. 构造方法
      4. 1.6.4. 常用方法
      5. 1.6.5. 例子