代码之家  ›  专栏  ›  技术社区  ›  tom

重写URLConnection的getInputStream以通过自定义协议接收数据

  •  1
  • tom  · 技术社区  · 7 年前

    我使用Java Web Start来获取并启动一个应用程序,为此,我必须通过所谓的jnlp协议下载数据。由于Java默认情况下不知道这个协议,所以我不得不编写自己的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);
    

    这是必要的,所以我不会得到以下错误:

    协议不支持输入

    1 回复  |  直到 7 年前
        1
  •  1
  •   df778899    7 年前

    通常,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();
    

    不确定这是为了什么环境。在我发现的窗户下 Desktop.open() 没有启动,因此直接调用 javaws .

    如果直接打给 爪哇 是一个选项,但是有一个更简单的方法,因为它可以直接从URL启动JNLP文件:

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