数码港 太原网站开发公司,定制网站建设功能报价表模板,沈阳app制作,鞍山招聘信息最新招聘转载自 Java魔法堂#xff1a;URI、URL#xff08;含URL Protocol Handler#xff09;和URN一、前言 过去一直搞不清什么是URI什么是URL#xff0c;现在是时候好好弄清楚它们了#xff01;本文作为学习笔记…转载自 Java魔法堂URI、URL含URL Protocol Handler和URN一、前言 过去一直搞不清什么是URI什么是URL现在是时候好好弄清楚它们了本文作为学习笔记以便日后查询若有纰漏请大家指正二、从URI说起 1. 概念URIUniform Resource Identifier统一资源标识符以字符串来表示某种资源的统一资源标识。格式为 [scheme:]scheme-specific-part[#fragment] [scheme:]组件 URI的名称空间标识。scheme-specific-part组件 用于标识资源内部格式由具体的 scheme 来决定。[#fragment]组件 井号(#)作为fragment组件的起始字符而fragment组件则用于聚焦到资源的某个部分。2. 绝对URI和相对URI绝对URI以scheme组件起始的完整格式如http://fsjohnhuang.cnblogs.com。表示以对标识出现的环境无依赖的方式引用资源。相对URI不以scheme组件起始的非完整格式如fsjohnhuang.cnblogs.com。表示以对依赖标识出现的环境有依赖的方式引用资源。实例当前页面地址为http://fsjohnuang.cnblogs.com
// html snippet
a idtest hreftest.comtest.com/a// js snippet
scriptvar href document.getElementById(test).hrefconsole.log(href) // 显示 http://test.com
/script3. 不透明URI和分层URI不透明URIscheme-specific-part组件不是以正斜杠(/)起始的如mailto:fsjohnhuangxxx.com。由于不透明URI无需进行分解操作因此不会对scheme-specific-part组件进行有效性验证。分层URIscheme-specific-part组件是以正斜杠(/)起始的如http://fsjohnhuang.com。scheme-specific-part组件格式为 [//authority][path][?query] [//authority] 表示授权机构组件以一对正斜杠(//)起始可以基于主机(server-based)或注册(registry-based)而基于注册相对基于主机的数目较少并以正斜杠、问号或无后续字符作为authority组件的结束。而authority组件的具体格式为 [userinfo]host[:port] 。[userinfo] 用户账号。host 主机IP或域名。[:port] 通信端口号若省略则使用相应的scheme组件的默认端口号。示例 http://fsjohnhuanggithub.com:80/ [path] path组件表示根据authority组件识别资源的位置。path组件有一系列的路径片段(path segment)构成路径片段间以正斜杠(/)作为分隔符。若第一个路径片段以正斜杠(/)起始则为绝对路径否则称为相对路径。[?query] query组件用于识别要传递给资源的数据用于影响资源的响应的行为。4. 标准化(Normalization)、解析化(Resolution)和相对化(Relativization)标准化(Normalization)其实就是去除path组件中当前层(.)和上一层(..)这些冗余字符。如z/../y标准化为y。解析化(Resolution)以URI A作为基本URI来和另外一个URI一同解析为一个新的标准URI。如http://fsjohnhuang.com作为基本URI和z/../y一同解析成http://fsjohnhuang.com/y。相对化(Relativization)相对化其实就是解析化的相反操作。如http://fsjohnhuang.com作为基本URI和http://fsjohnhuang.com/z来作相对化操作得到/z。到这里我们可能会认为这不就跟平常的网站地址一样吗为啥大家叫网站地址为URL而不是URI呢互联网之父Tim Berners-Lee引入用于识别、定位和命名互联网资源的途径——URI、URL和URN。三者彼此关联URI的范畴位于体系的顶层URL和URN的范畴位于体系的底层。URIUniform Resource Identifier统一资源标识符URLUniform Resource Locator统一资源定位符URNUniform Resource Name统一资源名称。上图可知URL和URN必须是URI但URI却不一定是URL或URN。URI仅仅是资源名称而已知道了URI最多就是知道有这么一个名称的资源罢了至于如何获取与资源作交互则是毫无头绪不能定位或读取/写入资源而这个资源名称是永久持有还是暂时持有也没有相应的规定于是就有了URL和URN两个子集。首先URL和URN均继承了URI格式中的各组件然后在这基础上进行了各自的扩展URLURL URIscheme组件为部分已知的网络协议的URI子集 与scheme组件标识的网络协议匹配的协议处理器URL Protocol Handler)1. URI的scheme组件在URL中称为protocol组件一般http、https、ftp、file、data、jar等。2. URL Protocol Handler则是一种资源定位器和根据协议建立的约束规则与资源通信的读写机制用于定位、读写资源。如安装迅雷后点击ed2k的迅雷种子时则会自动打开迅雷下载界面这是为什么呢迅雷种子就是资源而ed2k就是资源URL的protocol组件而迅雷就是URL Protocol Handler。而protocol组件与URL Protocol Handler间的映射关系在windows下则存放在注册表中而Ubuntu中存放在/usr/share/applications/.desktop中。windows7下①. 快捷键“开始”r 弹出运行输入框输入regedit进入注册表②. 进入HKEY_CURRENT_USER/Software/Classes目录下③. ed2k目录下包含shell/Open/command目录右侧窗口有一个条名称为URL Protocol的REG_SZ记录表示这是一个URL Protocol记录没有这一条记录也不会有影响④. 点击command目录后右侧窗口有一条REG_SZ类型记录数据列为C:\Program Files (x86)\Thunder Network\Thunder\Program\ThunderNewTask.exe %1 表示ThunderNewTask.exe作为URL Protocol Handler而%1则是传递给Handler处理的URL。⑤. 其实ed2k中还少了一个DefaultIcon目录该目录下有一个REG_SZ类型的记录用于指定该类型协议文件的图标。ubuntu下在/usr/share/applications/.desktop文件下添加如下内容
[Desktop Entry]
EncodingUTF-8
Version1.0
TypeApplication
Terminalfalse
Exec/usr/bin/cloudjerun -c %u
Nametunesview
CommentSmall, easy-to-use program to access iTunesU media
Icon/usr/share/icons/hicolor/scalable/apps/tunesview.svg
CategoriesApplication;Network;
MimeTypex-scheme-handler/cloudje;Exec键值的占位符表
Add... Accepts...
%f a single filename.
%F multiple filenames.
%u a single URL.
%U multiple URLs.
%d a single directory. Used in conjunction with %f to locate a file.
%D multiple directories. Used in conjunction with %F to locate files.
%n a single filename without a path.
%N multiple filenames without paths.
%k a URI or local filename of the location of the desktop file.
%v the name of the Device entry.3. URL与资源地址关联当资源位置变更后URL也需要被修改。URNURN URIscheme组件为部分已知的网络协议的URI子集 与scheme组件标识的网络协议匹配的协议处理器URL Protocol Handler) 持久性/地址无关性URN用于持久性地标识Internet资源即使资源已经不存在或不可用时依然保持不变通过实际的持久性策略实现资源位置发生变化也不用修改URI地址无关性。然而通过持久性策略还可以实现一条URN对应N条URI如BT中的磁力链接Magnet URI scheme。如magnet:?xturn:btih:4D9FA761D69964B00DF0B3B0C9C1F968EA6C47D0xturn:ed2k:7655dbacff9395e579c4c9cb49cbec0ednbbb_sunflower_2160p_30fps_stereo_abl.mp4说了这么多是时候总结一下URI、URL和URN的关联和区别了1. 首先URI是基础URL和URN均属于URI2. URL URIscheme组件为部分已知的网络协议的URI子集 与scheme组件标识的网络协议匹配的协议处理器URL Protocol Handler)3. URN突出的是持久化通过具体的持久化策略实现地址无关性。 URN URIscheme组件为部分已知的网络协议的URI子集 与scheme组件标识的网络协议匹配的协议处理器URL Protocol Handler) 持久性/地址无关性。四、java.net.URI类和java.net.URL类 java当中对URI和URL单独提供java.net.URI和java.netURL两个操作类。java.net.URI中主要提供以下功能1. 验证URI格式
构造函数URI(String str)若格式不正确则抛出URISyntaxException
URI.create(String str)若格式不正确则抛出unchecked的IllegalArgumentException2. 提取URI各组件
getAuthority()
getFragment()
getHost()
getPath()
getPort()
getQuery()
getScheme()
getSchemeSpecificPart()
getUserInfo()3. 标准化、解析化和相对化
normalize()返回符合标准的URI新对象。如x/y/../z/./q-x/z/q
resolve(String/URI uri)进行反向解析以入参作为相对URI以resolve方法所属对象作为基本URI来得到一个新的标准的URI对象
relativize(URI uri)相对化操作就是获取URI中的相对URI实例
URI uriBase new URI(http://www.somedomain.com);
URI uriRelative new URI(x/../y);
URI uriResolve uriBase.resolve(uriRelative); // http://www.somedomain.com/y
URI uriRelativized uriBase.relativize(uriResolve); // y4. 将URI转成URL
URI#toURL()将URI转换为URL。注意不含任何搜索和读写资源的操作。java.net.URL中主要提供以下功能URL类是依据URL Protocol Handler来处理URL字符串的若没有相应的协议处理器则抛MalformedURLException。内置提供http、https、ftp、file和jar协议的URL Protocol Handler。而其他协议的处理器则需开发者自行继承URLStreamHandler来实现了。处理流程如下1. 查看处理器缓存HashTable handlers若存在缓存项则直接返回2. 若缓存中没有则查看是否有URLStreamHandlerFactory实例若存在则调用其createURLStreamHandler(String protocol)。默认情况下URLStreamHandlerFactory实例为null3. 若2中返回null则通过系统属性java.protocol.handler.pkgs获取以|分隔的包名列表然后逐一检查是否存在继承了URLStreamHandler的package.protocol.Handler类有则返回无则继续遍历4. 若3中遍历失败则检查是否存在继承了URLStreamHandler的system default package.protocol.Handler的内置类。5. 上述均失败则抛出MalformedURLException。类URL中除了提供获取各组件的方法外还提供了读写资源的方法如 InputStream openStream() 。下面我们通过URL类来读取t.txt文本文件的内容。
class Main{static void main(String[] args) throws IOException, MalformedURLException{String path1 d:\\t.txt, path2 file:/d:/t.txt;Main main new Main();main.readByFr(path1);main.readByUrl(path2);}// 通过FileInputStream的写法void readByFr(String path) throws IOException{FileReader fr new FileReader(path);try{int buf;while (-1 ! buf){buf fr.read();System.out.print((char)buf);}}finally{fr.close();}}// 通过URL的写法void readByURL(String path) throws MalformedURLException, IOException{URL url new URL(path);InputStreamReader reader new InputStreamReader(url.openStream());try{int buf;while (-1 ! buf){buf reader.read();System.out.print((char)buf);}}finally{reader.close();}}
}五、总结 上述内容若有纰漏请大家指正谢谢六、参考
http://kb.cnblogs.com/page/90838/
https://msdn.microsoft.com/en-us/library/ms478653.aspx
http://www.cnblogs.com/wang726zq/archive/2012/12/11/UrlProtocol.html
http://stackoverflow.com/questions/16376429/ubuntu-custom-url-protocol-handler
http://www.ibm.com/developerworks/cn/xml/x-urlni.html
http://baike.baidu.com/link?urlagsiO-syltdQC_SlhSBThijAD3kSC4DVZcfnNPvO_KxGYOMCVqhiI58BDrn6tG06vohsH-evK1x7BqUj_wnR-a
JDK7 API