​Java语言为网络编程提供了一套专门的类和接口,这些类与接口位于java.net包下。在这些类当中有很多属于通用类,也就是说它们适用于各种模式的网络编程,这些类主要包括:InetAddress、URL、URLConnection、URLDecoder、URLEncoder等,本小节将讲解这些类的使用方法。

15.2.1 InetAddress类

InetAddress类用来表示IP地址,它还有两个子类:Inet4Address和Inet6Address,它们分别代表IPv4地址和IPv6地址。InetAddress类没有公用的构造方法,而是通过静态方法获得其对象,如表15-1所示。​

表15-1 InetAddress产生对象的静态方法​

方法​

功能​

getByName(String host)​

方法根据主机获取对应的InetAddress对象​

getByAddress(byte[] addr)​

根据原始IP地址来获取对应的InetAddress 对象​

getLocalHost()​

获取本机IP地址对应的InetAddress​

此外,InetAddress类还提供了三个方法来获取InetAddress对象所对应的IP地址和主机名,如表15-2所示。​

表15-2 InetAddress类获得主机名和IP地址的方法​

方法

功能

String getCanonicalHostName()

获取此IP地址的全限定域名

String getHostAddres()

返回该InetAddress对象所对应的IP地址字符串

String getHostName()

获取此IP 地址的主机名

boolean isReachable(int timeout)

测试是否能到达指定的IP地址,测试时间为timeout毫秒

InetAddress类本身比较简单,它没有太多功能,主要是用来表示一个IP地址,下面的【例15_01】展示了InetAddress类的功能与用途。​

【例15_01 InetAddress类的使用】​

Exam15_01.java​

import java.net.InetAddress;
public class Exam15_01 {
public static void main(String[] args) {
try {
//根据主机名获得表示百度的InetAddress对象
InetAddress address = InetAddress.getByName("www.baidu.com");
System.out.println("百度是否可以到达:"+address.isReachable(2000));
System.out.println("百度的IP地址:"+address.getHostAddress());
//获得表示本机地址的netAddress对象(本机地址统一表示为127.0.0.1)
InetAddress local = InetAddress.getByAddress(new byte[]{127,0,0,1});
System.out.println("本机是否可以到达:"+local.isReachable(2000));
System.out.println("local的全限定域名:"+local.getCanonicalHostName());
}catch (Exception e){
e.printStackTrace();
}
}
}

【例15_01】的运行结果如图15-1所示。​

第十五章《网络编程》第2节:网络编程通用类_InetAddress

图15-1【例15_01】运行结果​

15.2.2 URLDecoder类和URLEncoder类

URLDecoder和URLEncoder用于完成普通字符串和application/x-www-form-urlencoded MIME字符之间的转换。application/x-www-form-urlencoded MIME字符串是一个很长的专业名词,为表述方便,本书简称其为“MIME字符串”。所谓MIME字符串是一种特殊的字符串,当URL地址中包含非西欧文字时,系统会将这些由非西欧文字组成的字符串转换成MIME字符串,最典型的例子就是使用某些浏览器在完成关键字搜索时会在地址栏中把被搜索的非西欧文字转换成MIME字符串,如图15-2所示。​

第十五章《网络编程》第2节:网络编程通用类_URL_02

图15-2地址栏中的MIME字符串​

图15-2是通过百度网搜索“学习”这两个字的结果,图片中方框内就是“学习”这两个字被转换成MIME字符串的结果。近几年被开发出的浏览器已经能够直接识别普通字符串,因此并不是所有的浏览器都在地址栏中以MIME字符串的形式展现非西欧文字信息。​

实际开发过程中,有时候会遇到把普通字符串和MIME字符串相互转换的情况,这时候就需要用到URLDecoder类和URLEncoder类。URLDecoder类有一个decode()静态方法,它可以把MIME字符串转换成普通字符串,而URLEncoder类包含一个encode()静态方法,它可以将普通字符串转换成MIME字符串。下面的【例15_02】展示了URLDecoder类和URLEncoder类的作用。​

【例15_02 URLDecoder类和URLEncoder类的使用】

Exam15_02.java​

import java.net.*;
public class Exam15_02 {
public static void main(String[] args) {
try {
//把MIME字符串转换为普通字符串
String word = URLDecoder.decode("%E5%AD%A6%E4%B9%A0","UTF-8");//①
System.out.println("MIME字符串转为普通字符串:"+word);
//把普通字符串转换为MIME字符串
String mime1 = URLEncoder.encode("工作","GBK");
String mime2 = URLEncoder.encode("工作","UTF-8");
System.out.println("普通字符串转为MIME字符串(GBK):"+mime1);
System.out.println("普通字符串转为MIME字符串(UTF-8):"+mime2);
}catch (Exception e){
e.printStackTrace();
}
}
}

【例15_02】的运行结果如图15-3所示。​

第十五章《网络编程》第2节:网络编程通用类_URLDecoder_03

图15-3【例15_02】运行结果​

从图15-3可以看出:同样是“工作”两个字,以GBK和UTF两种编码形式进行转换的结果并不相同。这是因为MIME字符串的每个字节的数据都会被表示为%XX的形式,GBK编码规则中,每个汉字占2个字节,所以转换结果有4个%XX,而UTF-8编码规则中,每个汉字占3个%XX,所以转换结果有6个%XX。此外还可以看出:浏览器在把汉字转换为MIME字符串时是以UTF-8的形式编码的。​

15.2.3 URL类

URL是Uniform Resource Locator的缩写,翻译成中文就是“统一资源定位器”。Java语言的URL类用来指定网络上某个资源的位置。“资源”这个概念比较大,它可以是一个简单的文件或目录,也可以是更为复杂的对象引用,例如对数据库或搜索引擎的查询。一般来说,URL满足以下格式:​

protocol://host:port/resourcename

在这个格式中,protocol表示协议的名称,host表示主机,主机也可以由一个域名来表示,port表示端口号,而resourcename表示资源的名称。我们在打开网页的时,在浏览器地址栏中输入的就是这样的格式,例如:​

​http://www.studyjava.com:8080/index.jsp​

在这个网站地址中,http就是协议名称,www.studyjava.com是以域名形式表示的主机,8080是端口号,index.jsp是资源名称,由于网站服务器一般有默认端口号和默认的首页文件,不需要在地址栏中明确写出,所以大部分情况下访问一个网站的首页格式会简略成:​

​http://www.studyjava.com​

URL类有很多构造方法,但通常情况下程序员都会用一个字符串来当构造方法的参数,这个字符串实际上就是资源的地址,例如:​

new URL("http://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png");

当创建好一个URL对象后,就可以调用它的各种方法完成对资源的访问和操作。URL定义了很多用于访问资源的方法,如下面的表15-3所示。​

表15-3 URL类的方法​

方法

功能

String getFile()

获取该URL的资源名

String getHost()

获取该URL的主机名

String getPath()

获取该URL的路径部分

int getPort()

获取该URL的端口号

String getProtocol()

获取该URL的协议名称

String getQuery()

获取该URL的查询字符串部分

URLConection openConnection()

返回一个URLConnection对象,它代表了与URL所引用的远

程对象的连接

InputStream openStream()

打开与此URL的连接,并返回一个用于读取该URL资源的输入流

在这些方法中,最有用的就是openStream()方法,通过这个方法能够获得一个读取资源的流,使用这个流就能把网络上的资源下载到本地硬盘。下面的【例15_03】展示了URL类的使用方法。​

【例15_03 URL类的使用】

Exam15_03.java​

import java.io.*;
import java.net.*;
public class Exam15_03 {
public static void main(String[] args) {
String path;
//百度首页图片
path = "http://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png";
try {
URL url = new URL(path);//创建URL对象
System.out.println("资源名称:"+url.getFile());
System.out.println("主机名:"+url.getHost());
System.out.println("资源路径部分:"+url.getPath());
System.out.println("端口号:"+url.getPort());
System.out.println("协议名:"+url.getProtocol());
//打开读取资源的流
InputStream stream = url.openStream();
FileOutputStream fos = new FileOutputStream("D://baidu.png");
int r;
//复制文件
while ((r=stream.read())!=-1){
fos.write(r);
}
}catch (Exception e){
e.printStackTrace();
}
}
}

【例15_03】中,所创建的URL对象代表百度首页的图片,程序中使用url对象获取了资源名称、主机名、资源路径、端口号、协议名等各项信息,并使用openStream()获得读取资源的流,之后配合FileOutputStream流把资源文件复制到本地硬盘,这实际上就实现了资源文件的下载。【例15_03】的运行结果如图15-4所示。​

第十五章《网络编程》第2节:网络编程通用类_Java_04

图15-4【例15_03】运行结果​

从图15-4可以看出:url的端口号为-1,这是因为在创建url时没有指出端口号,虚拟机不会返回真实的端口号,只是按照创建url时参数字符串path来获取端口号,如果没有指出端口号则getPort()方法返回-1。当运行完本例后,可以看到计算机D盘根目录下出现了一个baidu.png,它就是被下载的资源文件。

本文字版教程还配有更详细的视频讲解,小伙伴们可以点击这里观看。