日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

URI 源码分析

發(fā)布時(shí)間:2024/9/30 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 URI 源码分析 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

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

URI 引用包括最多三個(gè)部分:模式、模式特定部分和片段標(biāo)識(shí)符。一般為:
模式:模式特定部分:片段
如果省略模式,這個(gè)URI引用則是相對(duì)的。如果省略片段標(biāo)識(shí)符,這個(gè)URI引用就是一個(gè)純URI。

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

構(gòu)造

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中構(gòu)造方法
1. 根據(jù)提供的一個(gè)uri字符串構(gòu)造一個(gè)URI對(duì)象。
2. 主要針對(duì)層次的URI。通過 模式、服務(wù)器地址、文件路徑、片段標(biāo)識(shí)構(gòu)造URI。
3. 主要針對(duì)層次的URI。通過 模式、授權(quán)機(jī)構(gòu)、文件路徑、查詢條件、片段標(biāo)識(shí)構(gòu)造URI。
4. 主要針對(duì)層次的URI。通過 模式、用戶信息、服務(wù)器地址、端口、文件路徑、查詢條件、片段標(biāo)識(shí)構(gòu)造URI。
5. 主要針對(duì)非層次URI。通過 模式、模式特定部分和片段標(biāo)識(shí)創(chuàng)建URI。

create方法

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

如果可以確認(rèn)URI的格式正確,可使用create的工廠方法創(chuàng)建URI。因?yàn)樵摲椒ú粫?huì)拋出URISyntaxException異常。

是否透明URL

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

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

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


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

判斷URI中是否存在“/”符號(hào),如果存在就是有層次結(jié)構(gòu)的URI。
如果存在“/”,則調(diào)用parseAuthority方法進(jìn)行解析path。

URI獲取各部分信息

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

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

    getScheme、getHost、getPort這三個(gè)方法沒有Raw方法,是因?yàn)檫@三部分不會(huì)出現(xiàn)非ascii的字符。

    resolve 方法

    resolve方法可以將相對(duì)URI轉(zhuǎn)換成絕對(duì)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);

    根據(jù)a獲取b的絕對(duì)路徑

    打印結(jié)果為: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(片段標(biāo)識(shí))。如果child只有片段標(biāo)識(shí)則執(zhí)行2.1。否則執(zhí)行3。
    2.1 如果child的fragment和base的片段標(biāo)識(shí)一樣,就直接返回base的url
    2.2 把base不包含fragment的部分和child的fragment構(gòu)造一個(gè)新的URI返回。
  • 判斷child的scheme不為空則直接返回child。不為空說明他是絕對(duì)路徑。
  • 根據(jù)base的URI各部分構(gòu)造child的絕對(duì)路徑URI并返回。
  • relativize 方法

    relativize 方法可以將絕對(duì)路徑的URI轉(zhuǎn)換成相對(duì)路徑的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相對(duì)a的相對(duì)路徑。

    打印的結(jié)果為: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。不是層次結(jié)構(gòu)的uri是沒有相對(duì)路徑的。
  • 判斷兩個(gè)URI的scheme和授權(quán)機(jī)構(gòu)是否不同,如果不同則直接返回child。
  • 判斷base是否“/”結(jié)尾,如果不是則加上“/”
  • 判斷child是否以base開頭,如果不是則直接返回child。
  • 返回child中,不包含base的部分,構(gòu)造一個(gè)新URI返回。
  • 本人簡書blog地址:http://www.jianshu.com/u/1f0067e24ff8????
    點(diǎn)擊這里快速進(jìn)入簡書

    GIT地址:http://git.oschina.net/brucekankan/
    點(diǎn)擊這里快速進(jìn)入GIT

    總結(jié)

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

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。