`
yourenyouyu2008
  • 浏览: 282147 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

如何增加自定义协议 protocol

阅读更多

协议的使用

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 {
        ..........

    }

分享到:
评论

相关推荐

    java开源包3

    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...

    JAVA上百实例源码以及开源项目源代码

    原理是初始化颜色选择按钮,然后为颜色选择按钮增加事件处理事件,最后实例化颜色选择器。 Java二进制IO类与文件复制操作实例 16个目标文件 内容索引:Java源码,初学实例,二进制,文件复制  Java二进制IO类与文件...

    Netty:基于Java NIO的网络服务器Netty生产实例

    Netty作为之前及现在不断学习Netty道路上持续集成项目Netty心跳实现客户端及服务端聊天实现完成Netty回声服务器使用WebSocket实现点对点聊天功能WebSocket实现群聊功能及上下线提醒增加Netty UDP协议实现使用第三方...

    JAVA上百实例源码以及开源项目

    原理是初始化颜色选择按钮,然后为颜色选择按钮增加事件处理事件,最后实例化颜色选择器。 Java二进制IO类与文件复制操作实例 16个目标文件 内容索引:Java源码,初学实例,二进制,文件复制  Java二进制IO类与文件...

    java开源包1

    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...

    java开源包11

    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...

    java开源包2

    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...

    java开源包6

    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...

    java开源包5

    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...

    java开源包10

    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...

    java开源包4

    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...

    java开源包8

    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...

    java开源包7

    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...

    java开源包9

    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...

    java开源包101

    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...

    Java资源包01

    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...

    路由器配置实例--100例

    1 禁止CDP(Cisco Discovery Protocol)。如: Router(Config)#no cdp run Router(Config-if)# no cdp enable 2 禁止其他的TCP、UDP Small服务。 Router(Config)# no service tcp-small-servers Router(Config)# no ...

    网络组建域管理课件2

     实现Web服务的通信协议是HTTP(Hypertext Transfer Protocol:超文本传输协议),它定义了HTTP的通信交换机制:HTML(hypertext Markup Language:超文本标记语言)用来描述Web上发布的信息,浏览器通过解释执行HTML...

    超级有影响力霸气的Java面试题大全文档

     ArrayList 和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,...

Global site tag (gtag.js) - Google Analytics