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 实例。

 

 

 

Java代码     收藏代码
  1. URL.setURLStreamHandlerFactory(new MyURLStreamHandlerFactory());  

(代码 1 

Java代码     收藏代码
  1. class MyURLStreamHandlerFactory implements URLStreamHandlerFactory{  
  2.         @Override  
  3.         public URLStreamHandler createURLStreamHandler(String protocol) {  
  4.             return null;  
  5.         }   
  6.           
  7. }  

(代码 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. 实现类必须又默认构造器。

      结合代码分析,如下:

Java代码     收藏代码
  1. URL httpURL = new URL(null"http://www.google.com",URLStreamHandler)null);  
  2. URLConnection urlConn = httpURL.openConnection();  

 

(代码 3 

 

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

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

(EOF)

 

 

http://mercyblitz.iteye.com/blog/735529

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值