URL协议处理器Handler

URL组成

  URL格式: protocol://[authority]hostname:port/resource?queryString
  说明:每种协议对应一种特定handler进行解析处理,JDK内置了HTTP 、 File 、 FTP和Jar等协议的。

Handler

   作用:每个Handler解析一种特定的协议,获取资源;
  命名规范: Handler类的命名模式为 [包路径].[协议].Handler,JDK内置Handler的包路径为“sun.net.www.protocol”,如下图所示:
      这里写图片描述

创建过程:

  1. 首先,如果创建URL时指定了Handler,则使用该Handler;
  2. 其次,如果设定了URLStreamHandlerFactory,则根据Protocol从其获取对应Handler实例;
  3. 最后,根据系统参数java.protocol.handler.pkgs指定的类创建Handler实例;
       if (handler == null &&
            (handler = getURLStreamHandler(protocol)) == null) {
            throw new MalformedURLException("unknown protocol: " + protocol);
        }
        this.handler = handler;

设置包路径创建Handler

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

      if (handler == null) {
                String packagePrefixList = null;

                packagePrefixList
                    = java.security.AccessController.doPrivileged(
                    new sun.security.action.GetPropertyAction(
                        protocolPathProp,""));
                if (packagePrefixList != "") {
                    packagePrefixList += "|";
                }

                // REMIND: decide whether to allow the "null" class prefix
                // or not.
                packagePrefixList += "sun.net.www.protocol";

                StringTokenizer packagePrefixIter =
                    new StringTokenizer(packagePrefixList, "|");

                while (handler == null &&
                       packagePrefixIter.hasMoreTokens()) {

                    String packagePrefix =
                      packagePrefixIter.nextToken().trim();
                    try {
                        String clsName = packagePrefix + "." + protocol +
                          ".Handler";
                        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();
                        }
                    } catch (Exception e) {
                        // any number of exceptions can get thrown here
                    }
                }
            }

自定义URL协议

  实现URLStreamHandlerFactory或者设置系统参数“java.protocol.handler.pkgs”即可。

参考:

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

猜你喜欢

转载自blog.csdn.net/yangguosb/article/details/80759554