日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

URI 源码分析

發布時間:2024/9/30 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 URI 源码分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

需要提前了解下什么是URI,及URI和URL的區別:
[URI、 URL 和 URN 的區別](http://www.jianshu.com/p/09ac6fc0f8cb)

URI 引用包括最多三個部分:模式、模式特定部分和片段標識符。一般為:
模式:模式特定部分:片段
如果省略模式,這個URI引用則是相對的。如果省略片段標識符,這個URI引用就是一個純URI。

URI是對URL的抽象,不僅包括統一資源定位符URL,還包括統一資源名URN。實際上使用的URI大多都是URL。在java中,URI使用java.net.URI類表示,URI類只能標識資源,和解析URI,而不能獲取URI所標識的資源(URN是無法定位到資源的)。

構造

public URI(String str) throws URISyntaxException {new Parser(str).parse(false); }public URI(String scheme, String host, String path, String fragment)throws URISyntaxException{this(scheme, null, host, -1, path, null, fragment); }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{ ... }public URI(String scheme, String ssp, String fragment) throws URISyntaxException {new Parser(toString(scheme, ssp, null, null, null, -1, null, null, fragment)).parse(false); }

URI類提供了5中構造方法
1. 根據提供的一個uri字符串構造一個URI對象。
2. 主要針對層次的URI。通過 模式、服務器地址、文件路徑、片段標識構造URI。
3. 主要針對層次的URI。通過 模式、授權機構、文件路徑、查詢條件、片段標識構造URI。
4. 主要針對層次的URI。通過 模式、用戶信息、服務器地址、端口、文件路徑、查詢條件、片段標識構造URI。
5. 主要針對非層次URI。通過 模式、模式特定部分和片段標識創建URI。

create方法

public static URI create(String str) {try {return new URI(str);} catch (URISyntaxException x) {throw new IllegalArgumentException(x.getMessage(), x);} }

如果可以確認URI的格式正確,可使用create的工廠方法創建URI。因為該方法不會拋出URISyntaxException異常。

是否透明URL

URI通常情況下都是層次(帶“/”)的,但是也有不透明(沒有“/”)的,層次的URI包含模式,主機,站點等各個部分,當然可能某些部分不包含,但是不透明的URI只包含三個部分,Scheme,Scheme-specific-part,Fragment.
如:mailto:jijianshuai@infcn.com.cn

public boolean isOpaque() {return path == null; }

判斷path是否為空,如果為空則是不透明的,說明URI中沒有“/”。


在URI構造器中解析URI,代碼:new Parser(str).parse(false);

判斷URI中是否存在“/”符號,如果存在就是有層次結構的URI。
如果存在“/”,則調用parseAuthority方法進行解析path。

URI獲取各部分信息

  • 獲得模式
    public String getScheme();
  • 獲得模式特定部分
    public String getSchemeSpecificPart();
    public String getRawSchemeSpecificPart();
  • 獲得片段
    public String getFragment();
    public String getRawFragment();
  • 獲得授權機構
    public String getAuthority();
    public String getRawAuthority()
    授權機構包括:用戶信息、服務器地址(域名或ip)、端口
    user:password@localhost:80
  • 獲取片段標識
    public String getFragment()
    public String getRawFragment()
  • 獲取服務器地址(域名或ip)
    public String getHost()
  • 獲取路徑
    public String getPath()
    public String getRawPath()
    路徑包括(目錄結構和文件部分)。如:/dir/index.html
  • 獲取端口
    public int getPort()
    如果沒有端口則返回-1;
  • 獲取URI的查詢字符串
    public String getQuery()
    public String getRawQuery()
  • 獲取用戶信息
    public String getUserInfo()
    public String getRawUserInfo()
  • 如果URI是非透明只能獲取到1~3個信息。
    如果URI是層次結構則能獲取所有信息。

    方法中帶Raw的,是獲取編碼后的URI部分信息。非ascii的字符需要進行編碼,不帶Raw的方法是解碼后的信息。

    getScheme、getHost、getPort這三個方法沒有Raw方法,是因為這三部分不會出現非ascii的字符。

    resolve 方法

    resolve方法可以將相對URI轉換成絕對URI。示例如下:

    URI a = URI.create("http://localhost:8080/index.html"); URI b = URI.create("user/userInfo.html"); URI c = a.resolve(b); System.out.println(c);

    根據a獲取b的絕對路徑

    打印結果為:http://localhost:8080/user/userInfo.html

    源碼如下
    public URI resolve(URI uri) {return resolve(this, uri); }private static URI resolve(URI base, URI child) {// check if child if opaque first so that NPE is thrown// if child is null.if (child.isOpaque() || base.isOpaque())return child;// 5.2 (2): Reference to current document (lone fragment)if ((child.scheme == null) && (child.authority == null)&& child.path.equals("") && (child.fragment != null)&& (child.query == null)) {if ((base.fragment != null) && child.fragment.equals(base.fragment)) {return base;}URI ru = new URI();ru.scheme = base.scheme;ru.authority = base.authority;ru.userInfo = base.userInfo;ru.host = base.host;ru.port = base.port;ru.path = base.path;ru.fragment = child.fragment;ru.query = base.query;return ru;}// 5.2 (3): Child is absoluteif (child.scheme != null)return child;URI ru = new URI(); // Resolved URIru.scheme = base.scheme;ru.query = child.query;ru.fragment = child.fragment;// 5.2 (4): Authorityif (child.authority == null) {ru.authority = base.authority;ru.host = base.host;ru.userInfo = base.userInfo;ru.port = base.port;String cp = (child.path == null) ? "" : child.path;if ((cp.length() > 0) && (cp.charAt(0) == '/')) {// 5.2 (5): Child path is absoluteru.path = child.path;} else {// 5.2 (6): Resolve relative pathru.path = resolvePath(base.path, cp, base.isAbsolute());}} else {ru.authority = child.authority;ru.host = child.host;ru.userInfo = child.userInfo;ru.host = child.host;ru.port = child.port;ru.path = child.path;}// 5.2 (7): Recombine (nothing to do here)return ru; }
  • 是否是非透明URI,如果是,則直接返回child。
  • 判斷child是否只有fragment(片段標識)。如果child只有片段標識則執行2.1。否則執行3。
    2.1 如果child的fragment和base的片段標識一樣,就直接返回base的url
    2.2 把base不包含fragment的部分和child的fragment構造一個新的URI返回。
  • 判斷child的scheme不為空則直接返回child。不為空說明他是絕對路徑。
  • 根據base的URI各部分構造child的絕對路徑URI并返回。
  • relativize 方法

    relativize 方法可以將絕對路徑的URI轉換成相對路徑的URI。

    URI a = URI.create("http://localhost:8080/"); URI b = URI.create("http://localhost:8080/index.html"); URI c = a.relativize(b); System.out.println(c);

    獲取b相對a的相對路徑。

    打印的結果為:index.html

    private static URI relativize(URI base, URI child) {// check if child if opaque first so that NPE is thrown// if child is null.if (child.isOpaque() || base.isOpaque())return child;if (!equalIgnoringCase(base.scheme, child.scheme)|| !equal(base.authority, child.authority))return child;String bp = normalize(base.path);String cp = normalize(child.path);if (!bp.equals(cp)) {if (!bp.endsWith("/"))bp = bp + "/";if (!cp.startsWith(bp))return child;}URI v = new URI();v.path = cp.substring(bp.length());v.query = child.query;v.fragment = child.fragment;return v; }
  • 判斷child是否不是透明URI,如果不是則直接返回child。不是層次結構的uri是沒有相對路徑的。
  • 判斷兩個URI的scheme和授權機構是否不同,如果不同則直接返回child。
  • 判斷base是否“/”結尾,如果不是則加上“/”
  • 判斷child是否以base開頭,如果不是則直接返回child。
  • 返回child中,不包含base的部分,構造一個新URI返回。
  • 本人簡書blog地址:http://www.jianshu.com/u/1f0067e24ff8????
    點擊這里快速進入簡書

    GIT地址:http://git.oschina.net/brucekankan/
    點擊這里快速進入GIT

    總結

    以上是生活随笔為你收集整理的URI 源码分析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。