网络编程 - java.net.URL

《Java网络编程》内容摘抄和整理

我们知道URL是用于定位资源的一串有特定的规则的字符串。这个有规则的字符串内部包含的内容有很多,比如访问资源所有的协议、资源所在的主机地址、处理访问的端口等等。当然我们拿到这样的表示URL的字符串,可以通过自己解析的方式来获取我们需要的信息,不过java本着一切都是对象的原则,已经为我们定义了这样一个代表URL的类,从而方便我们操作。这个类就是java.net.URL类。

类简介

java.net.URL类是对统一资源定位符的抽象。它扩展了java.lang.Object,是一个final类,不能对其派生子类。它不依赖于继承来配置不同类型URL的实例,而使用了策略(strategy)设计模式。协议处理器就是策略,URL类构成了上下文,通过它来选择不同的策略。

URL是不可变的。构造一个URL对象后,其字段不在改变。这有一个副作用:可以保证它们是"线程安全"的。

类属性

URL是通过指定资源位置从而定位资源的一种方式,它是URI的一个子集。URI一般化的语法由以下五个有次序和层级的组件组成:

URI = scheme:[//authority]path[?query][#fragment]

其中,authority部分分为三个子组成部分:

authority = [userinfo@]host[:port]

组成各部分图示如下:

URI_syntax_diagram.png

java.net.URL类是对URL字符串的抽象,类中定义的属性即表示URL字符串的各个组成部分。

类属性如下:

类属性 说明 详述
authority 授权机构 URL字符串中的authority
file 文件部分 URL字符串中的path[?query]
host 主机名 URL字符串中host
port 端口 URL字符串中port
protocol 协议 URL字符串中的scheme
query 查询字符串 URL字符串中的query
ref 片段标识符 URL字符串中的fragment
path 路径 URL字符串中的path
userInfo 用户信息 URL字符串中authority部分的userinfo内容

file: Java不会把URL分解为单独的路径和文件部分。从主机名后的第一个斜线(/)一直到开始片段标识符的#号之前的字符,都被认为是文件部分。

构造方法

java.net.URL类提供了如下的构造方法:

public URL(String spec) throws MalformedURLException;
public URL(String protocol, String host, int port, String file) throws MalformedURLException;
public URL(String protocol, String host, int port, String file, URLStreamHandler handler) throws MalformedURLException;
public URL(String protocol, String host, String file) throws MalformedURLException;
public URL(URL context, String spec) throws MalformedURLException;
public URL(URL context, String spec, URLStreamHandler handler) throws MalformedURLException;

不同的构造函数所需的信息有所不同,使用哪个构造函数取决于你有哪些信息以及信息的形式。如果试图为一个不支持的协议创建URL对象,或者如果URL的语法不正确,所有这些构造函数都会抛出一个MalformedURLException异常。

支持哪些协议取决于具体实现。所有虚拟机都支持的协议只有http和file,而且后者名声很不好。如今Java还支持https、jar和ftp。一些虚拟机还支持mailto和gopher,以及一些定制协议如doc、netdoc、systemresource和Java在内部使用的verbatim。

示例1:从字符串构造URL

@Test
public void test1() {
    try {
        URL url = new URL("http://www.baidu.com");
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }
}

示例2:由组成部分构造URL

@Test
public void test2() {
    try {
        URL url = new URL("http", "www.eff.org", "/blueribbon.html#intro");
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }
}
@Test
public void test3() {
    try {
        URL url = new URL("http", "fourier.dur.ac.uk", 8000, "/~dma3mjh/jsci/");
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }
}

示例3:构造相对URL

@Test
public void test4() {
    try {
        URL u1 = new URL("http://www.ibiblio.org/javafaq/index.html");
        URL u2 = new URL(u1, "mailinglists.html");
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }
}

从URL获取数据

URL类有几个方法可以从URL获取数据:

public final InputStream openStream() throws java.io.IOException;
public URLConnection openConnection() throws java.io.IOException;
public URLConnection openConnection(Proxy proxy) throws java.io.IOException;
public final Object getContent() throws IOException;
public final Object getContent(Class[] classes) throws java.io.IOException;

openStream()

openStream()方法连接到URL所引用的资源,在客户端和服务器之间完成必要的握手,返回一个InputStream,可以由此读取数据。从这个InputStream获得的数据是URL引用的原始内容(即未经解释的内容):如果读取ASCII文本则为ASCII;如果读取HTML文件则为原始HTML,如果读取图像文件则为二进制图片数据等。它不包括任何HTTP首部或者与协议有关的任何其他信息。可以像读取其他InputStream一样读取这个InputStream。

示例:

@Test
public void test5() {
    try {
        URL url = new URL("http://www.lolcats.com");
        try (InputStream in = url.openStream()) {
            int c;
            while ((c = in.read()) != -1)
                System.out.write(c);
        }
    } catch (IOException ex) {
        ex.printStackTrace();
    }
 }

openConnection()

openConnection()方法为指定的URL打开一个socket,并返回一个URLConnection对象。URLConnection表示一个网络资源的打开的连接。如果调用失败,则openConnection()会抛出一个IOException异常。

示例:

@Test
public void test6() {
    try {
        URL u = new URL("https://news.ycombinator.com");
        try {
            URLConnection uc = u.openConnection();
            InputStream in = uc.getInputStream();
            // 从连接读取
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    } catch (MalformedURLException ex) {
        ex.printStackTrace();
    }
}

如果希望与服务器直接通信,应当使用这个方法。通过URLConnection,你可以访问服务器发送的所有数据:除了原始的文档本身外(如HTML、纯文本、二进制图像数据),还可以访问这个协议指定的所有元数据。例如,如果模式是HTTP或HTTPS,URLConnection允许你访问HTTP首部以及原始HTML。

你可能感兴趣的:(网络编程 - java.net.URL)