URI URL URN简介及其在Java中的应用

来源:互联网 发布:朋友借身份证开淘宝店 编辑:程序博客网 时间:2024/05/29 16:43
常常遇到URI,URL这两个概念,但是一直都没有仔细去区分,前几天看书遇到了就决定花点时间来区分这两个概念,与这两个概念一起的还有URN,下面是它们的定义:
URI:Uniform Resource Identifier,统一资源标识符
URL:Uniform Resource Locator,统一资源定位符
URN:Uniform Resource Name,统一资源名

URI

URI以特定的语法标识一个资源的字符串,所标识的资源可以是文件,也可以是一个电子邮件地址,一本书或者其他东西,绝对URI由URI模式和特有部分组成,他们之间用冒号隔开,格式为:

模式:模式特有部分#片段([<scheme>:]<scheme-specific-part>[#<fragment>])

以上模式特有部分的语法依赖于所使用的特有模式,比较常用的模式有:
  • file:本地磁盘上的文件,Java中File类的toURI()方法可能会输出:file:/home/
  • http:使用超文本传输协议的万维网服务器,例如http://www.google.com.hk
  • ftp:FTP服务器
  • mailto:电子邮件地址
  • telnet:与基于Telnet协议的服务器的连接
其中URI中的模式特有部分没有特定的语法,但是分多模式都定义了层次的模式特有部分,如http、ftp等。层次的模式形式如下:

//授权机构/路径?查询([//<authority>]<path>[?query])

但是也有些模式的模式特有部分不是层次形式,如邮件URImailto:packagecomponent@gmail.com的模式是mailto,模式特有部分是packagecomponent@gmail.com。

目前大部分URI使用Internet主机作为授权机构,在这种情况下,授权机构还可以包括可选的用户名和端口:

用户信息@主机:端口([<userInfo>@]<host>[:port])

如URIftp://user1:password1@example.com:8080/path/text.txt的授权机构是user1:password1@example.com:8080,用户信息是user1:password1,主机是example.com,端口是8080,路径是/path/text.txt。

路径是授权机构用来确定所标识资源的字符串,不同授权机构可以将不同路径指向不同的资源。

URL和URN

URI可以分为两种:URL和URN。
URL指向Internet上位于某个闻之的某个资源,例如http://zh.wikipedia.org/wiki/%E7%BB%9F%E4%B8%80%E8%B5%84%E6%BA%90%E6%A0%87%E5%BF%97%E7%AC%A6#RFC_3305这个URL指向站点http://zh.wikipedia.org中的资源文件/wiki/%E7%BB%9F%E4%B8%80%E8%B5%84%E6%BA%90%E6%A0%87%E5%BF%97%E7%AC%A6,#号后面的部分就是片段部分,片段部分一般标识资源文件的文件中的部分,通过HTML中的标签可以指定片段部分的位置
URN用于标识资源本身,不关注具体位置,也不限于标识Internet资源,例如一本书的URN可以是:urn:isbn:12345

URL用于标识Internet上资源的位置,使用URL可以指定用于访问服务器的协议(http,ftp)、服务器名称和服务器上文件的位置,这样就能通过这个URL定位一个服务器上的一个文件(如果这个文件存在)
URL的语法是:
协议://用户信息@主机名:端口/路径?查询#片段([<protocol>:][//[<userInfo>@]<hostname>[:<port>]]<path>[?<query>][#<fragment>])
URL是URI的一种,所以URL的语法同样遵循URI的格式模式:模式特有部分#片段([<scheme>:]<scheme-specific-part>[#<fragment>]),如URL中的协议即为URI格式中的模式。

Java中的URL

自此,对URI和URL有了一个理论的认识,那么在实际编程中怎么使用这些协议呢?
在Java中,有URI类和URL类,URI.toURL()方法可以将URI对象转换为URL对象,下面是读取一个URL的示例:
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.MalformedURLException;import java.net.URI;public class URITest {public static void main(String[] args) throws MalformedURLException, IOException {URI uri = URI.create("http://www.baidu.com");BufferedReader br = new BufferedReader(new InputStreamReader((uri.toURL().openStream())));String line = null;while((line = br.readLine()) != null) {System.out.println(line);}}}
URL.openStream()方法可以获取到资源的输入流,通过这个方法可以很方便的读取资源数据。但是这样只能读取该URL所指定的资源文件,如果要向服务器提交数据,则需结合URLConnection,URLStreamHandler这两个抽象类和URLStreamHandlerFactory这个接口。所以就需要编写一个URLConnection类继承自URLConnection,一个URLStreamHandler类继承自URLStreamHandler和一个URLStreamHandlerFactory类实现URLStreamHandlerFactory接口,这样才可以实现向网页提交数据。具体交互的代码就不写了,下面给出一个如何编程来实现这些类和接口以及如何使用这些类的示例:
URLStreamHandlerFactory类:
import java.net.URLStreamHandler;import java.net.URLStreamHandlerFactory;public class FsURLStreamHandlerFactory implements URLStreamHandlerFactory {private URLStreamHandler handler;public FsURLStreamHandlerFactory(URLStreamHandler handler) {this.handler = handler;}@Overridepublic URLStreamHandler createURLStreamHandler(String protocol) {System.out.println(this.getClass().getName());return handler;}}
URLStreamHandler类
import java.io.IOException;import java.net.URL;import java.net.URLConnection;import java.net.URLStreamHandler;public class FsUrlStreamHandler extends URLStreamHandler {@Overrideprotected URLConnection openConnection(URL u) throws IOException {System.out.println(this.getClass().getName());return new FsUrlConnection(u);}}
URLConnection类
import java.io.IOException;import java.net.URL;import java.net.URLConnection;public class FsUrlConnection extends URLConnection {protected FsUrlConnection(URL url) {super(url);}@Overridepublic void connect() throws IOException {System.out.println(this.getClass().getName() + ":connecting to " + url);}}
在URL处理中,先使用URL.setURLStreamHandlerFactory()方法来设置URLSreamHandlerFactory类,可以从URLStreamHandlerFactory类中返回一个URLStreamHandler类对象,而URLStreamHandler类中则可以返回URLConnection类的对象,通过这些机制就可以使用URL来处理一个特定的请求。测试代码如下:
import java.io.IOException;import java.net.URI;import java.net.URL;import java.net.URLConnection;public class URLTest {public static void main(String[] args) throws IOException {URI uri = URI.create("http://en.wikipedia.org/wiki/URL#History");URL.setURLStreamHandlerFactory(new FsURLStreamHandlerFactory(new FsUrlStreamHandler()));URL url = uri.toURL();URLConnection connection = url.openConnection();connection.connect();}}
大体使用方式就是这样了,更详细的使用方式以后再写篇博客来学习

Reference:
《Hadoop技术内幕:深入解析Hadoop Common和HDFS架构设计与实现原理》

统一资源标志符





0 0
原创粉丝点击