媒体发稿网站开发,中文安卓开发工具,小型网站有哪些,信息门户系统转载自 Java URL协议扩展实现在信息交互系统设计中#xff0c;不乏有自定义通讯协议设计。本章会介绍如何利用 java.net.URL 类来自定义协议。一般而言#xff0c; URL 的格式是#xff1a; protocol://[authority]hostname:port/resource?queryString 。 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.pkgscom.acme.protocol 代表处理实现类皆在这个包下。如果需要多个包的话那么使用“ |” 分割。比如 -D java.protocol.handler.pkgscom.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 代码 3 中没有配置 URLStreamHandler 的类并且代码 2 中工厂类没有实现了 HTTP 协议。这样 URL 会获取默认的 HTTP 处理类 sun.net. www.protocol.http.Handler 。Java 1.5 开始支持网络代理的操作因此 URLStreamHandler 实现类尽量覆盖 openConnection(URL) 和openConnection(URL,Proxy) 两个方法。