Java URL协议扩展实现

转载自   Java URL协议扩展实现

在信息交互系统设计中,不乏有自定义通讯协议设计。本章会介绍如何利用 java.net.URL 类来自定义协议。

 

      一般而言, URL 的格式是: protocol://[authority]hostname:port/resource?queryString 。 URL 类能够解析出protocol 、 hostname 、 port 等信息。 Protocol 决定了交互规范,通用的协议,比如 HTTP 、 File 、 FTP 等协议, JDK 自带了默认的通讯实现。当然,自定义实现是允许的。 Hostname 和 port 一般用于 Socket 或者基于Socket 其他协议通讯方式。 Resource 即资源上下文。可能读者利用 URL ,通过指定协议( protocol )来获取指定资源的读写,比如 JDK 内置了 HTTP 、 File 、 FTP 等协议的处理方法。哪么 URL 的工作原理到底是怎么样的呢?

      在成功地构造 URL 实例之后, URL API 中定义了一个 openConnection() 方法,返回一个java.net.URLConnection 抽象类型的实例。不过,这里 URL 对象是代理对象(组合了 其 对象),实际调用的是, java.net.URLStreamHandler 对象的 openConnection() 方法。

      java.net.URLStreamHandler 对象可以有两条途径得到:实现 java.net.URLStreamHandler ,或者实现java.net.URLStreamHandlerFactory 。

      java.net.URLStreamHandler 是一个工厂类,通过 openConnection(java.net.URL) 方法来创建java.net.URLConnection 的实例。 java.net.URLStreamHandler 实现灵活度很大,既可以通过不同 protocol 的URL 实例,产生 java.net.URLConnection 对象。还可以通过相同 protocol 的多个 URL 对象,来产生对象。通用性实现,一种协议对应一个 java.net.URLStreamHandler 实现。比如,在 SUN JDK 中 sun.net.www.protocol 子包下面的多个 Handler 类就是很好的例子。如果读者有兴趣,可以去看看相关实现。

      1. 通过 java.net.URLStreamHandlerFactory 机制

      java.net.URLStreamHandlerFactory ,顾名思义,它是 java.net.URLStreamHandler 的工厂,即抽类工厂接口。通过调用 createURLStreamHandler(String protocol) 来创建 java.net.URLStreamHandler 对象。因此,建议java.net.URLStreamHandlerFactory 实现类应该采用 one protocol one hander 的模式, SUN JDK 也采用该模式。

     大致解了他们关系之后,再通过 UML Class diagram 来熟悉下:    

 

(图 1 )

 

     图 1 所示, URL 包含了名为 factory 的 URLStreamHandlerFactory 类对象和 handler 的 URLStreamHandler的实例对象。对于 URL 而言, handler 对象是必须的,因为前面说到实际处理 openConnection() 方法是 handler对象,而 factory 并不是必须的。接下来,来分析这两个对象是如何和 URL 交互的。

     在 URL 的构造方法中,暂时不用关心协议字符串等参数,更多的关注于 URL context 和 URLStreamHandler参数。 URL 实例能够依赖于 URL context ,当 URLStreamHandler 参数为空的情况下,当前 URL 实例将会采用URL context 的 URLStreamHandler 成员对象。当 Context 和 URLStreamHandler 参数都为空的时。 URL 会调用getURLStreamHandler ( String) 方法,从而根据协议 (protocol) 获得协议 URLStreamHandler 对象。

     在 URL 底层实现中,最初会初始化一个 protocol 和 hander 键值关系的 Map 映射。如果找到已有的映射关系,立即返回 URLStreamHandler 对象(第一次是取不到 URLStreamHandler 对象的)。

     如果找不到的话,并且 URL 类中的类成员 URLStreamHandlerFactory 实例不为空的情况下,这个实例通过URL#setURLStreamHandlerFactory 方法来注册。 getURLStreamHandler 方法会调用这个类成员的createURLStreamHandler(String) 方法来创建 URLStreamHandler 实例。

URL.setURLStreamHandlerFactory(new MyURLStreamHandlerFactory()); 

(代码 1 )

class MyURLStreamHandlerFactory implements URLStreamHandlerFactory{  @Override  public URLStreamHandler createURLStreamHandler(String protocol) {  return null;  }   }  

(代码 2 )

当 createURLStreamHandler 方法返回 null 的时候, URL 的 getURLStreamHandler 方法会采用URLStreamHandler 处理机制。

 

      2. 通过 java.net.URLStreamHandler 机制

      2.1. 实现类包路径定义

        通过 JVM 启动参数 -D java.protocol.handler.pkgs 来设置 URLStreamHandler 实现类的包路径,例如 -Djava.protocol.handler.pkgs=com.acme.protocol , 代表处理实现类皆在这个包下。如果需要多个包的话,那么使用“ |” 分割。比如 -D java.protocol.handler.pkgs=com.acme.protocol|com.acme.protocol2 。 SUN 的 JDK内部实现类均是在 sun.net.www.protocol. 包下,不必设置。 路径下的协议实现类,采用先定义先选择的原则 。

      2.2. 实现类的命名模式

      类的命名模式为 [package_path].[protocol].Handler ,比如默认实现” sun.net.www.protocol.[protocol].Handler”, 比如 HTTP 协议的对应的处理类名为 -sun.net. www.protocol.http.Handler 。同样,自定义实现的处理类,例如, JDNI 协议实现类命名 com.acme.protocol.jndi.Handler 。

      2.3. 实现类必须又默认构造器。

      结合代码分析,如下:

URL httpURL = new URL(null, "http://www.google.com",(URLStreamHandler)null);  
URLConnection urlConn = httpURL.openConnection();  

(代码 

 

      代码 3 中没有配置 URLStreamHandler 的类,并且代码 2 中工厂类没有实现了 HTTP 协议。这样, URL 会获取默认的 HTTP 处理类 sun.net. www.protocol.http.Handler 

      Java 1.5 开始支持网络代理的操作,因此 URLStreamHandler 实现类尽量覆盖 openConnection(URL) openConnection(URL,Proxy) 两个方法。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/328652.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

axure8 事件改变样式_AxureRP8实战手册-案例2(文本框:边框变色)

案例2. 文本框:边框变色案例来源:百度-登录界面案例效果:光标进入文本框时:(图1-6)案例描述:在登录界面中,包含用户名与密码的输入框。当焦点进入输入框时,输入框边框与内部图标变为蓝色;失去…

URL的getFile()和getPath()方法的区别

转载自 URL的getFile()和getPath()方法的区别 import java.net.MalformedURLException; import java.net.URL; public class dd { /** * param args */ public static void main(String[] args) { try { URL url new URL("file://ftp.yoyodyne.com/pub/files/fo…

webpack打包发布

npm run dev npm run dist --线上 git status git add . git commit -am "online adapter" git push git pull git branch --查看当前分支是在哪里master 还是 admin yarn install v1.3.2 yarn run dist -- 打包 fe-deply.sh --shell脚本 自动发布脚本 gi…

介绍开源的.net通信框架NetworkComms

Networkcomms 是一款C# 语言编写的TCP/UDP通信框架 作者是英国人 以前是收费的 目前作者已经开源 开源地址是:https://github.com/MarcFletcher/NetworkComms.Net networkcomms通讯框架使用简单方便,性能稳定. 从github上下载到源码后,需要Visual studio安装nuget 加载相关D…

dplayer js控制 自动全屏_vue-video-player 通过自定义按钮组件实现全屏切换效果【推荐】...

最近公司的产品上线,一些高级功能在基础版本中不对用户开发,通过视频的形式展示。产品开发用的是 vue, 经同事介绍使用了vue-video-player视频播放插件,通过 demo案例很快实现了视频播放效果class"vjs-custom-skin"ref"videoP…

新闻发布项目——实体类(comment)

package bdqn.newsMange.entity;import java.util.Date;/*** 新闻评论表*/ public class comment {private int commentID;//编号private String cmmUser;//用户名private String ip;//ipprivate String cmmContent;//内容private int newsID;//新闻IDprivate Date cmmDate;//…

java字符串格式化:String.format()方法的使用

转载自 java字符串格式化:String.format()方法的使用常规类型的格式化 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象。熟悉C语言的读者应该记得C语言的sprintf()方法,两者有类似之处。format()方法有两种重载形式。 l for…

java web每天定时执行任务(四步轻松搞定)

https://www.cnblogs.com/LiSheng97625/p/4648739.html java web每天定时执行任务(四步轻松搞定) 第一步: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44…

从Unity3D编译器升级聊起Mono

接前篇Unity 5.3.5p8 C#编译器升级,本文侧重了解一些Mono的知识。 Unity3D的编译器升级 新升级的Mono C#编译器(对应Mono 4.4) Unity编辑器及播放器所使用的Mono运行时还未升级。 新编译器仍针对C# 4,是旧的编译器也支持的版本。 …

bat脚本中获取上级目录_批处理bat命令--获取当前盘符和当前目录和上级目录

批处理命令获取当前盘符和当前目录%~d0 是当前盘符%cd% 是当前目录可以用echo %cd%进行打印测试以下例子是命令行编译Visual Studio编写的程序:echo offset b%cd% //将当前目录保存到参数b中,等号前后不要有空格C:cd program filescd microsoft visual studiocd com…

日期类的加减及java中所以日期类的操作算法大全

转载自 日期类的加减及java中所以日期类的操作算法大全1.计算某一月份的最大天数Calendar timeCalendar.getInstance(); time.clear(); time.set(Calendar.YEAR,year); //year 为 int time.set(Calendar.MONTH,i-1);//注意,Calendar对象默认一月为0 int daytime.getActu…

使用Spring的@Scheduled实现定时任务

https://blog.csdn.net/prisonbreak_/article/details/49180307 使用Spring的Scheduled实现定时任务 2015年10月16日 16:23:21 阅读数:103485更多 个人分类: Java开发 Spring配置文件xmlns加入 xmlns:task"http://www.springframework.org/sch…

新闻发布项目——实体类(categoryTB)

package bdqn.newsMange.entity; /*** 新闻类别实体类* author Administrator**/ public class categoryTB {private int categoryID;//编号private String categoryName;//类别名public int getCategoryID() {return categoryID;}public void setCategoryID(int categoryID) {…

.NET Core 系列5 :使用 Nuget打包类库

NuGet是个开源项目,项目包括 NuGet VS插件/NuGet Explorer/NuGetServer/NuGet命令行等项目,.NET Core项目完全使用Nuget 管理组件之间的依赖关系,Nuget已经成为.NET 生态系统中不可或缺的一个组件,从项目角度,将项目中…

foxmail 不知道这样的主机_华为P50真机图!网友:早知道这样,就不加价买mate40了...

hello,大家好,欢迎收看本期节目由于各方面原因,今年的华为mate40系列确实很难抢不少心急的用户甚至是加价买了入手之后有的用户有开始后悔了,当然不是该机不好而是他们看到了疑似华为P50的真机渲染图它的正面并没有丑陋的双打孔&a…

F#年度调查结果概述

本文要点 年度社区调查向600多名开发人员了解了他们的F#使用情况;在工作中,F#的最大好处包括正确性、让不合法状态不可达以及能够更轻松地解决复杂的问题;大多数F#开发人员仍然使用Windows作为他们的开发平台之一,但使用Mac和Linu…

java Date获取 年月日时分秒

转载自 java Date获取 年月日时分秒 package com.util;import java.text.DateFormat; import java.util.Calendar; import java.util.Date;public class Test {public void getTimeByDate(){Date date new Date();DateFormat df1 DateFormat.getDateInstance();//日期格式&…

anroid 内存溢出 Bitmap OutOfMemoryError

Bitmap OutOfMemoryError 2014年06月09日 09:55:28 阅读数:2434 标签: OutOfMemoryErrorBitmap回收 更多 个人分类: 异常问题和解决办法 在创建Bitmap的时候由于对象过多而没有即使回收,导致的内存不足: java.lang…

wxml报错原因_C#生成、解析xml文件以及处理报错原因

转载自:http://blog.csdn.net/lilinoscar/article/details/21027319简单的介绍一下生成XML文件以及解析,因为有些数据不一定放到数据库,减少链接数据库用xml还是比较好些。如果遇到问题也就是解析时报错,对于解析,可以…

新闻发布项目——接口类(UserDao)

package bdqn.newsMange.Dao;import java.util.List;import bdqn.newsMange.entity.User;/*** 用户信息接口* author Administrator**/ public interface UserDao {//查询public List<User>getAllUesr();//添加public int addUser(User user);//修改public int updateUse…