c5 URLs and URIs - The URI Class

The URI Class

URI是URL的一般化,URI中不仅包括URL,还包括URNs(Uniform Resource Names)。大部分实际使用的URI是URL,而大部分标准化的,特殊化的,比如XML,就是用URI定义的。

java中java.net.URI,  java.net.URL 主要的区别:

URI纯粹是对资源的唯一定义和对URIs的解析(parsing),没有提供获取URI指定的资源的方法

URI对象表示一个相对的URI,而URL会将URI绝对化。

怎么选择二者的使用呢?一般来说,如果要从server端获取内容,用URL,其他情况,考虑使用URI,如果两者都用,用toURL(),toURI()转换吧!


Constructing a URI

public URI(String uri) throws URISyntaxException
public URI(String scheme, String schemeSpecificPart, String fragment)
    throws URISyntaxException
public URI(String scheme, String host, String path, String fragment)
    throws URISyntaxException
public URI(String scheme, String authority, String path, String query,
    String fragment) throws URISyntaxException
public URI(String scheme, String userInfo, String host, int port,
    String path, String query, String fragment) throws URISyntaxException
与URL不同的地方,URI不需要理解底层的(underlying)的协议,只要语法正确就可以。

URI voice = new URI("tel:+1-800-9988-9938");
URI web   = new URI("http://www.xml.com/pub/a/2003/09/17/stax.html#id=_hbc");
URI book  = new URI("urn:isbn:1-565-92870-9");

构建一个新的URI,也可以

URI styles = URI.create(
    "ftp://anonymous:elharo%40ibiblio.org@ftp.oreilly.com:21/pub/stylesheet");
不像构造方法,这个方法不会抛出URISyntaxException,但如果该URI是畸形的(malformed),会抛出IllegalArgumentException。


The Parts of the URI

URI 组成:

scheme:scheme-specific-part:fragment

如果scheme省略,就是一个相对URI,如果fragment省略,就是一个pure URI。

scheme-specific-part部分没有明确的语法规定,像URL的该部分是下面这样的:

//authority/path?query#fragment


URI的getter方法

public String getScheme()
public String getSchemeSpecificPart()
public String getRawSchemeSpecificPart()
public String getFragment()
public String getRawFragment()
getRawFoo()返回encoded的URI部分

getFoo():先解码decoded,再返回。(解码any percent-escaped characters )

没有getRawScheme(),因为scheme部分URI有特别要求,不会被编码。scheme只能由:ASCII、digits,+、-、. 组成。


有scheme的URI是absolute URI,没有的是relative URI。

public boolean isAbsolute()

scheme-specific-part和具体scheme有关,是hierarchical的isOpaque()返回false,没有的返回true。

public boolean isOpaque()

如果URI是opaque,那只能获取scheme,scheme-specific-part,和fragment部分。如果不是,则还可以获取

public String getAuthority()
public String getFragment()
public String getHost()
public String getPath()
public String getPort()
public String getQuery()
public String getUserInfo()
上面的方法返回的都是decoded后的,如果要返回encoded的,则

public String getRawAuthority()
public String getRawFragment()
public String getRawPath()
public String getRawQuery()
public String getRawUserInfo()

java并不能每次都能对authority部分进行语法检测,结果是无法返回host,port等,这种情况下要调用parseServerAuthority()强制对authority再解析。

public URI parseServerAuthority() throws URISyntaxException

public class URISplitter {
	  public static void main(String args[]) {
	    for (int i = 0; i < args.length; i++) {
	      try {
	        URI u = new URI(args[i]);
	        System.out.println("The URI is " + u);
	        if (u.isOpaque()) {
	          System.out.println("This is an opaque URI.");
	          System.out.println("The scheme is " + u.getScheme());
	          System.out.println("The scheme specific part is "
	              + u.getSchemeSpecificPart());
	          System.out.println("The fragment ID is " + u.getFragment());
	        } else {
	          System.out.println("This is a hierarchical URI.");
	          System.out.println("The scheme is " + u.getScheme());
	          try {
	            u = u.parseServerAuthority();
	            System.out.println("The host is " + u.getHost());
	            System.out.println("The user info is " + u.getUserInfo());
	            System.out.println("The port is " + u.getPort());
	          } catch (URISyntaxException ex) {
	            // Must be a registry based authority
	            System.out.println("The authority is " + u.getAuthority());
	          }
	          System.out.println("The path is " + u.getPath());
	          System.out.println("The query string is " + u.getQuery());
	          System.out.println("The fragment ID is " + u.getFragment());
	        }
	      } catch (URISyntaxException ex) {
	          System.err.println(args[i] + " does not seem to be a URI.");
	      }
	      System.out.println();
	    }
	  }
	}

Resolving Relative URIs

3种方法在absolute URI和relative URI间转换

public URI resolve(URI uri)
public URI resolve(String uri)
public URI relativize(URI uri)

URI absolute = new URI("http://www.example.com/");
URI relative = new URI("images/logo.png");
URI resolved = absolute.resolve(relative);
output: http://www.example.com/images/logo.png

URI top = new URI("javafaq/books/");
URI resolved = top.resolve("jnp3/examples/07/index.html");
output:javafaq/books/jnp3/examples/07/index.html with no scheme or authority


URI absolute = new URI("http://www.example.com/images/logo.png");
URI top = new URI("http://www.example.com/");
URI relative = top.relativize(absolute);
output:images/logo.png



Equality and Comparison

equaels():scheme和authority部分不区分大小写。其他部分大小写敏感,除了16进制数字。

hashcode():与equaels一致,URI equaels的hashcode一定相同,不equaels的hashcode也不大可能相同。

URI实现了comparabl接口,参考compareTo()方法,看比较顺序。

URI只和自身类型的比较,否则抛出ClassCastException.


String Representations

public String toString()
public String toASCIIString()

toString()返回unencoded string,可能语法上不是一个正确的URI,适合human reading,不适合retrieval。

toASIIString()返回 URI的encoded string,语法上一定是正确的。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值