java - 重写 URLConnection 的 getInputStream 以通过自定义协议(protocol)接收数据

标签 java inputstream java-web-start jnlp urlconnection

我正在使用 Java Web Start 来获取并启动应用程序,为此我必须通过所谓的 jnlp 协议(protocol)下载数据。由于默认情况下 Java 不知道该协议(protocol),因此我必须编写自己的 URL 流处理程序。

我的问题是我不知道如何实现getInputStream方法,

// the custom URL stream handler
URL.setURLStreamHandlerFactory((String protocol)
    -> "jnlp".equals(protocol) ? new URLStreamHandler() {
    @Override
    protected URLConnection openConnection(URL url) throws IOException {
        return new URLConnection(url) {
            @Override
            public void connect() throws IOException {
                System.out.println("connected");
            }
            @Override
            public InputStream getInputStream() throws IOException {
                /* -------------------- */
                /* What to put in here? */
                /* -------------------- */
            }
        };
    }
} : null);

// Constructing the parametrized URL for Java Web Start...
URL url = new URL("jnlp", "localhost", 8080,
    "application-connector/app?"
    + params.entrySet().stream().map(Object::toString)
        .collect(joining("&")));

// Downloading and starting the application...
final File jnlp = File.createTempFile("temp", ".jnlp");
byte[] buffer = new byte[8192];
int len;
while ((len = url.openStream().read(buffer)) != -1) {
    new FileOutputStream(jnlp).write(buffer, 0, len);
}
Desktop.getDesktop().open(jnlp);

这是必要的,这样我就不会收到以下错误:

protocol doesn't support input

最佳答案

通常,JNLP 只能从 http://https: URL 下载。例如。 :

    URL url = new URL(
            "https://docs.oracle.com/javase/tutorialJWS/samples/uiswing/WallpaperProject/Wallpaper.jnlp");

    // Downloading and starting the application...
    final File jnlp = File.createTempFile("temp", ".jnlp");

    try (InputStream is = url.openStream();
            FileOutputStream fos = new FileOutputStream(jnlp)) {
        byte[] buffer = new byte[8192];
        int len;
        while ((len = is.read(buffer)) != -1) {
            fos.write(buffer, 0, len);
        }
    }

    System.out.println("JNLP file written to " + jnlp.getAbsolutePath());

    //Desktop.getDesktop().open(jnlp);
    new ProcessBuilder("cmd", "/c", "javaws", jnlp.getAbsolutePath())
            .start();

不确定其适用的环境。在 Windows 下,我发现 Desktop.open() 未启动,因此直接调用 javaws

如果可以选择直接调用 javaws,那么还有一种更简单的方法,因为它可以直接从 URL 启动 JNLP 文件:

    new ProcessBuilder("cmd", "/c", "javaws",
            "https://docs.oracle.com/javase/tutorialJWS/samples/uiswing/WallpaperProject/Wallpaper.jnlp")
                    .start();

关于java - 重写 URLConnection 的 getInputStream 以通过自定义协议(protocol)接收数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51722246/

相关文章:

java - android 新手问题 ArrayAdapter.setAdapter 上的空指针

java - 如果boolean在JVM中表示为int,那么它与Java的强类型是如何对应的呢?

Java 7 update 25 使我们的 java web start 应用程序失败且没有日志记录

java web start部署属性文件读取

java web start 替代方案

java - 替换除一个字符以外的所有内容

Java:设计问题 - 集合之间的最小对

java - 将List转换为InputStream而不创建中间文件

java - 当某些字节错误时,BitmapFactory.decodeStream(inputStream) 总是返回 null

java - 如何将多个不同的 InputStream 链接到一个 InputStream