注册和使用自定义 java.net.URL 协议 [英] Registering and using a custom java.net.URL protocol

查看:28
本文介绍了注册和使用自定义 java.net.URL 协议的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图从我的 java 程序中调用一个 custom url,因此我使用了这样的东西:

I was trying to invoke a custom url from my java program, hence I used something like this:

URL myURL;
try {
   myURL = new URL("CustomURI:");
   URLConnection myURLConnection = myURL.openConnection();
   myURLConnection.connect();
} catch (Exception e) {
   e.printStackTrace();
}

我收到以下异常:

java.net.MalformedURLException:未知协议:CustomURI在 java.net.URL.(来源不明)在 java.net.URL.(来源不明)在 java.net.URL.(来源不明)在 com.demo.TestDemo.main(TestDemo.java:14)

java.net.MalformedURLException: unknown protocol: CustomURI at java.net.URL.(Unknown Source) at java.net.URL.(Unknown Source) at java.net.URL.(Unknown Source) at com.demo.TestDemo.main(TestDemo.java:14)

如果我从浏览器触发 URI 那么它会按预期工作,但是如果我尝试从 Java Program 调用它,那么我会收到上述异常.

If I trigger the URI from a browser then it works as expected but if I try to invoke it from the Java Program then I am getting the above exception.

以下是我尝试过的步骤(我确实遗漏了一些东西,请让我知道):

Below are the steps I tried (I am missing something for sure, please let me know on that):

步骤 1:在 java.protocol.handler.pkgs

第 2 步:从 URL 触发自定义 URI

代码:

public class CustomURI {

public static void main(String[] args) {

    try {
        add("CustomURI:");
        URL uri = new URL("CustomURI:");
        URLConnection uc = uri.openConnection();            
        uc.connect();
    } catch (Exception e) {
        e.printStackTrace();
    }

}

public static void add( String handlerPackage ){

    final String key = "java.protocol.handler.pkgs";

    String newValue = handlerPackage;
    if ( System.getProperty( key ) != null )
    {
        final String previousValue = System.getProperty( key );
        newValue += "|" + previousValue;
    }
    System.setProperty( key, newValue );
    System.out.println(System.getProperty("java.protocol.handler.pkgs"));

}

}

当我运行此代码时,我在控制台中打印了 CustomURI:(来自 add 方法),但是当 URL 为使用 CustomURI: 作为构造函数初始化:

When I run this code, I am getting the CustomURI: printed in my console (from the add method) but then I am getting this exception when the URL is initialized with CustomURI: as a constructor:

Exception in thread "main" java.lang.StackOverflowError
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at java.net.URL.getURLStreamHandler(Unknown Source)
at java.net.URL.<init>(Unknown Source)
at java.net.URL.<init>(Unknown Source)
at sun.misc.URLClassPath$FileLoader.getResource(Unknown Source)
at sun.misc.URLClassPath.getResource(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.net.URL.getURLStreamHandler(Unknown Source)
at java.net.URL.<init>(Unknown Source)
at java.net.URL.<init>(Unknown Source)

请建议如何进行这项工作.

Please advice how to make this work.

推荐答案

  1. 创建自定义URLConnectionconnect() 方法中执行工作的实现.

  1. Create a custom URLConnection implementation which performs the job in connect() method.

public class CustomURLConnection extends URLConnection {

    protected CustomURLConnection(URL url) {
        super(url);
    }

    @Override
    public void connect() throws IOException {
        // Do your job here. As of now it merely prints "Connected!".
        System.out.println("Connected!");
    }

}

不要忘记相应地覆盖和实现其他方法,例如 getInputStream().由于问题中缺少此信息,因此无法提供更多详细信息.

Don't forget to override and implement other methods like getInputStream() accordingly. More detail on that cannot be given as this information is missing in the question.

创建自定义URLStreamHandleropenConnection() 中返回它的实现.

Create a custom URLStreamHandler implementation which returns it in openConnection().

public class CustomURLStreamHandler extends URLStreamHandler {

    @Override
    protected URLConnection openConnection(URL url) throws IOException {
        return new CustomURLConnection(url);
    }

}

如有必要,不要忘记覆盖和实现其他方法.

Don't forget to override and implement other methods if necessary.

创建自定义URLStreamHandlerFactory 根据协议创建并返回它.

Create a custom URLStreamHandlerFactory which creates and returns it based on the protocol.

public class CustomURLStreamHandlerFactory implements URLStreamHandlerFactory {

    @Override
    public URLStreamHandler createURLStreamHandler(String protocol) {
        if ("customuri".equals(protocol)) {
            return new CustomURLStreamHandler();
        }

        return null;
    }

}

请注意,协议是始终小写.

最后在应用程序启动时通过 URL#setURLStreamHandlerFactory()

Finally register it during application's startup via URL#setURLStreamHandlerFactory()

URL.setURLStreamHandlerFactory(new CustomURLStreamHandlerFactory());

请注意 Javadoc 明确表示最多可以设置一次.因此,如果您打算在同一应用程序中支持多个自定义协议,则需要生成自定义 URLStreamHandlerFactory 实现以将它们全部包含在 createURLStreamHandler() 方法中.

Note that the Javadoc explicitly says that you can set it at most once. So if you intend to support multiple custom protocols in the same application, you'd need to generify the custom URLStreamHandlerFactory implementation to cover them all inside the createURLStreamHandler() method.

或者,如果您不喜欢得墨忒耳定律,请将其全部放在匿名类中以进行代码精简:

Alternatively, if you dislike the Law of Demeter, throw it all together in anonymous classes for code minification:

URL.setURLStreamHandlerFactory(new URLStreamHandlerFactory() {
    public URLStreamHandler createURLStreamHandler(String protocol) {
        return "customuri".equals(protocol) ? new URLStreamHandler() {
            protected URLConnection openConnection(URL url) throws IOException {
                return new URLConnection(url) {
                    public void connect() throws IOException {
                        System.out.println("Connected!");
                    }
                };
            }
        } : null;
    }
});

如果您已经使用 Java 8,请将 URLStreamHandlerFactory 功能接口替换为 lambda 以进一步缩小:

If you're on Java 8 already, replace the URLStreamHandlerFactory functional interface by a lambda for further minification:

URL.setURLStreamHandlerFactory(protocol -> "customuri".equals(protocol) ? new URLStreamHandler() {
    protected URLConnection openConnection(URL url) throws IOException {
        return new URLConnection(url) {
            public void connect() throws IOException {
                System.out.println("Connected!");
            }
        };
    }
} : null);

<小时>

现在您可以按如下方式使用它:


Now you can use it as follows:

URLConnection connection = new URL("CustomURI:blabla").openConnection();
connection.connect();
// ...

或者按照规范使用小写协议:

Or with lowercased protocol as per the spec:

URLConnection connection = new URL("customuri:blabla").openConnection();
connection.connect();
// ...

这篇关于注册和使用自定义 java.net.URL 协议的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆