协议的使用
public URL(String spec)
public URL(URL context, String spec, URLStreamHandler handler)
代码使用
new URL("http://yourenyouyu2008.iteye.com/admin/blogs/new")
会去匹配http协议处理
new URL(null,"myproc:///admin/blogs/new",new Handler())
使用自定义的myproc协议处理,可以不向jvm注册
new URL("myproc:///admin/blogs/new")
使用自定义的myproc协议处理,但必须向jvm注册myproc协议
协议表示法:第一个:之前的是协议名称,//后面的my是主机名称,8080是端口号,端口号后面必须跟/,端口号必须是数字;/d:/aa表示 file
new URL("db://my:8080/d:/aa");
没有主机名和端口号,协议后面直接是file
new URL("db:d:/aa");
在具体协议URLConnection子类中可以从URL中获得url信息,比如主机,端口号等。
配置方式使用
<resource source='brules:d:/rules/fns.drl' type='DRL' />
由于没法配置协议处理类,所以必须向jvm注册自定义的协议
注册协议
URL的static URLStreamHandler getURLStreamHandler(String protocol) 方法用于获取获取协议处理类
URL提供了两种注册协议的途径。
1)设置URLStreamHandlerFactory,2)设置jvm启动参数java.protocol.handler.pkgs。
两者可以同时使用。
设置URLStreamHandlerFactory
URL的方法
public static void setURLStreamHandlerFactory(URLStreamHandlerFactory fac) {
synchronized (streamHandlerLock) {
if (factory != null) {
throw new Error("factory already defined");
}
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkSetFactory();
}
handlers.clear();
factory = fac;
}
}
public interface URLStreamHandlerFactory {
URLStreamHandler createURLStreamHandler(String protocol);//在方法中可以通过判断协议名称返回对应的Handler,这样通过HandlerFactory方式就能定义多种协议了。
}
整个jvm只能设置一次,再次设置不起作用(设置时做 if (factory != null)判断)。调用URL.setURLStreamHandlerFactory(fac)。
一般是在服务器的代码中设置,比如tomcat,jboss ,was等,用于注册服务器自己的协议,应用级没法设置,因为服务器已经设置过了,应用即使设置了也不起作用。
启动参数-Djava.protocol.handler.pkgs
通过-Djava.protocol.handler.pkgs=cn.ccb.wfcp注册自定义协议的包。要求协议处理类的类名必须是Handler,包名的最后是协议名。示例如下,定义了brules协议。
package cn.ccb.wfcp.brules;
public class Handler extends URLStreamHandler {
之所以这样要求包名和类名,是为了能一次配置多种协议。比如cn.ccb.wfcp.brules2下面也有 Handler ,那么会同时支持brules和brules2两种协议。
如果要定义多个协议包就用"|"分割,比如-Djava.protocol.handler.pkgs=cn.ccb.wfcp|cn.ccb.wfcp22.
jvm内置的协议也是按照上面的方式定义的,但不用通过-Djava.protocol.handler.pkgs注册,而是将内置的协议包拼接到后面(将sun.net.www.protocol字符串拼到Djava.protocol.handler.pkgs定义的字符串后面)。内置协议都在sun.net.www.protocol包下面(7种内置协议)。
sun.net.www.protocol.file.Handler
sun.net.www.protocol.http.Handler
sun.net.www.protocol.jar.Handler
。。。。
获取到Handler类名后去加载class。Class cls = null;
try {
cls = Class.forName(clsName);
} catch (ClassNotFoundException e) {
ClassLoader cl = ClassLoader.getSystemClassLoader();
if (cl != null) {
cls = cl.loadClass(clsName);
}
}
if (cls != null) {
handler =
(URLStreamHandler)cls.newInstance();
}
但是只能加载到jvm classpath下的class,内置协议的class都可以加载到。如果自定义的协议类不加入jvm 的 classpath就不能被加载到,所以必须放入jvm 的classpath中,一般情况下自定义的协议是业务相关的,这样就必须将业务相关的类也放入到jvm 的classpaht中,而业务类是在服务器中运行的,不应该放入更底层的jvm classpath中,要想办法让协议处理类与业务类解耦,这样业务类就不需要放入jvm classpath中了。
解耦示例如下,Handler ,RulesURLConnection ,IRulesFiles 三个类在jvm classpath中,将这3个类打成xxprotocol.jar,在jvm启动参数中指定 -cp xxprotocol.jar.
package cn.ccb.wfcp.brules;
。。。。。
public class Handler extends URLStreamHandler {
@Override
protected URLConnection openConnection(URL u) throws IOException {
return new RulesURLConnection(u);
}
}
package cn.ccb.wfcp.brules;
。。。。。
public class RulesURLConnection extends URLConnection {
@Override
public long getLastModified() {
return getIRulesFiles().getLastModified();
}
private IRulesFiles getIRulesFiles() {
IRulesFiles files = null;
try {
Class rulClass = null;
rulClass = Class.forName("cn.ccb.wfcp.brules.protocol.RulesFiles",
true, Thread.currentThread().getContextClassLoader());
//通过自定义classloader的方式控制实现类的加载
files = (IRulesFiles) rulClass.newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return files;
}
@Override
public InputStream getInputStream() throws IOException {
return getIRulesFiles().getInputStream();
}
@Override
public OutputStream getOutputStream() throws IOException {
return getIRulesFiles().getOutputStream();
}
package cn.ccb.wfcp.brules;
。。。。。。。。
public interface IRulesFiles {
public List<String> getRuleElements();
public long getLastModified();
public InputStream getInputStream() throws IOException;//用于输入
public OutputStream getOutputStream() throws IOException;//用于输出,不需要输出时可以不实现该方法
}
业务类,调用其他业务类
package cn.ccb.wfcp.brules.protocol;
。。。。
public class RulesFiles implements IRulesFiles{
@Override
public long getLastModified() {
return RuleFilesDAOImpl.instance().getLastModified();
}
@Override
public InputStream getInputStream() throws IOException {
List<InputStream> list = new ArrayList<InputStream>();
ByteArrayInputStream sinput = null;
for (String rule : getRuleElements()) {
System.out.println("---rule length:" + rule.length());
sinput = new ByteArrayInputStream(rule.getBytes());
list.add(sinput);
}
SequenceInputStream rulesInput = new SequenceInputStream(Collections.enumeration(list));
return rulesInput;
}
@Override
public OutputStream getOutputStream() throws IOException {
..........
}
相关推荐
"reliable-file-transfer-custom-protocol"项目正是关注于这个问题,它提出了一个自定义协议来实现可靠且高效的文件传输,声称其速度至少比传统的TCP/IP协议快1000倍。下面将详细探讨这个自定义协议的原理、设计考虑...
同时,为了保持与系统UIAlertView类似的使用方式,我们可以创建一个协议(Protocol),该协议包含一个展示警报框的方法,然后让自定义警报框类遵循这个协议。这样,调用者就可以像使用UIAlertView一样调用自定义警报...
FIX4.2协议允许在标准字段的基础上添加自定义字段,以满足特定机构或市场的特殊需求。此外,协议还支持可选字段,使得消息可以灵活地包含必要或非必要的信息。 **六、应用范围** FIX4.2协议不仅适用于股票市场,也...
4. **代码结构**:使用协议(Protocol)和委托(Delegate)模式,可以使得自定义AlertView的代码结构更加清晰,便于管理和扩展。 接下来,我们将关注如何实现这些自定义特性: 1. **创建自定义AlertView类**:通常...
同时,要注意自定义OID可能导致增加系统的监控负担,因此应谨慎使用,只针对真正需要监控的关键指标进行定制。 为了进一步学习和实践这个过程,可以参考提供的"如何自定义 OID.pdf"文件,它应该包含更详细的步骤和...
- **协议版本**:RDP Composited Remoting V2是RDP的一个特定版本,它在原有的基础上进行了改进,增加了新的功能和服务,例如更高级的图形处理能力和安全机制。 - **协议组成**:RDP协议主要由多个子协议组成,每...
2. **时间同步协议**:如果你的系统需要与其他网络设备保持时间同步,如NTP(Network Time Protocol),那么你需要定制时钟同步算法,确保本地时钟与远程服务器的时间一致。这可能涉及复杂的网络通信和误差校正。 3...
5. **修改和增加Tcl库**:NS2的仿真脚本是通过Tcl语言编写的,因此,实现自定义协议往往也需要对Tcl库进行相应的修改或增加,以便在仿真脚本中调用新的协议。 6. **支持混合网络仿真**:在某些情况下,添加协议可能...
Protocol_Buffer是一种强大的工具,用于通信协议和数据存储的结构化数据序列化。它提供了一种语言无关、平台无关且易于扩展的方法来处理复杂的数据结构。相比于XML等其他数据格式,Protocol_Buffer在数据大小、处理...
同时,通过设置协议(protocol)和代理(delegate),我们可以将alertView的确认和取消操作回调到调用它的视图控制器中,保持代码的清晰和可维护性。这将极大地提高开发效率,让我们的应用界面更加符合用户体验和...
不过,需要注意的是,自定义URLProtocol可能会增加代码的复杂性,因此在设计时应充分考虑性能和可维护性。此外,随着iOS版本的更新,URLSession的特性也在不断改进,可能需要适时调整策略以适应新特性。最后,对于...
面向协议编程(Protocol Oriented Programming,简称POP)是Swift 3.0以后由Apple提出的一种编程理念。这种编程范式充分利用了Swift语言的特点,比如协议扩展、协议继承等,与传统的面向对象编程(Object Oriented ...
ProtocolAnalyser框架的核心优势在于其对自定义协议的支持。无论是基于IP的TCP、UDP等通用协议,还是TUP、ISUP这样的电信协议,用户都可以根据需求定制解析策略。这得益于其强大的C++编程接口,开发者可以通过API...
SSL&TLS协议簇加解密流程.docx详细描述了SSL的升级版TLS(Transport Layer Security)协议,它扩展了SSL的功能,增加了更多加密算法和安全特性,如前向安全性,以增强数据保护。 安全协议导论.pdf和安全协议形式化...
二层协议报文透传利用二层隧道技术,确保二层协议(如生成树协议、LACP)和用户自定义协议报文在设备间透明转发。例如,当两个运行相同二层协议(如MSTP)的用户网络需要跨越骨干网进行通信时,常规情况下,由于目的...
为了增加扩展性,我们可以引入协议(Protocol)和委托设计模式(Delegate)。创建一个自定义的TabBarDelegate协议,其中包含一些回调方法,比如`- (void)tabBar:(CustomTabBar *)tabBar didSelectItemAtIndex:...
这意味着即便协议增加了新的方法或属性要求,现有的类型仍然可以通过使用协议扩展中的默认实现而无需修改。 - **向后兼容**:通过添加协议扩展来为现有协议添加新功能,而不破坏已有的代码。这种机制使得在不改变...
1. **多协议支持**:PPP帧头包含一个协议标识字段,允许在同一链路上同时传输多种网络协议,增加了协议的灵活性和适应性。 2. **错误检测**:PPP引入了帧校验序列(FCS)字段,采用CRC(循环冗余校验)进行错误检测...
8. **拓展性**:RTMP协议允许开发者自定义命令和事件,增加了协议的灵活性和可扩展性,能够适应各种应用场景。 9. **错误处理**:RTMP协议定义了一系列错误代码和状态码,用于在客户端和服务器之间传递错误信息,...
以自定义协议“foo protocol”为例,该协议包含数据包类型、标识、序号和IP地址四个字段。注册协议时,会定义协议的端口号(如1234)和其他相关信息。 4. 新协议解析器的实现 对于foo protocol,可以创建一个解析器...