java - ChunkedInput 在 Jersey 中不起作用

标签 java rest jersey chunked

任何人都可以帮助我为什么 java 代码有问题并一次打印所有数据而不是将每个 block 打印为 javascript 代码

Java 代码:

import org.glassfish.jersey.client.ChunkedInput;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.Response;

public class RunClient {

    public static void main(String args[]) throws InterruptedException {
        Client client = ClientBuilder.newClient();
//2 is to increase amount of data and 3(seconds) is for time b/w chunked output  ,can be changed
        final Response response = client.target("http://jerseyexample-ravikant.rhcloud.com/rest/jws/streaming/2/3").request()
                .get();
        final ChunkedInput<String> chunkedInput = response.readEntity(new GenericType<ChunkedInput<String>>() {
        });
        String chunk;
        while ((chunk = chunkedInput.read()) != null) {
            System.err.println("Next chunk received: " );
            System.out.println(chunk);
        }


    }
}

JavaScript :(打开页面 http://jerseyexample-ravikant.rhcloud.com/rest/jws 然后按 F12 并在控制台中运行,因为不允许从其他域调用 javascript)

//2 is to increase amount of data and 3(seconds) is for time b/w chunked output  ,can be changed

var xhr = new XMLHttpRequest()
xhr.open("GET", "http://jerseyexample-ravikant.rhcloud.com/rest/jws/streaming/2/3", true)
xhr.onprogress = function () {
  console.log("PROGRESS:", xhr.responseText) ;console.log("\n");
}
xhr.send()

编辑:只是为了帮助它也适用于正常的 java 连接

        String uri = "http://jerseyexample-ravikant.rhcloud.com/rest/jws/streaming/3/1";
        URL url = new URL(uri);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        connection.setDoOutput(true);
        BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        String line;
        while ((line = in.readLine()) != null) {
            System.out.println(line);
        }
        in.close();

我的网络服务代码

@Path("streaming/{param}/{sleepTime}")
@GET
@Produces(MediaType.TEXT_PLAIN)
public ChunkedOutput<String> getChunkedStream(@PathParam("param") String loopcount,@PathParam("sleepTime") String sleepTime) throws Exception {

    final ChunkedOutput<String> output = new ChunkedOutput<>(String.class);
    final Integer val=Integer.parseInt(loopcount);
    final Integer isleepTime=Integer.parseInt(sleepTime)*1000;
    new Thread(new Runnable() {

        @Override
        public void run() {
            try {
                StringBuffer chunk = null;

                for (int i = 0; i < 10; i++) {
                        chunk = new StringBuffer();
                    for (int j = 0; j < val; j++) {
                        chunk.append(" Message #" + i+ "#"+j);
                    }
                        output.write(chunk.toString()+"\n");
                    System.out.println("write");
                    Thread.sleep(isleepTime);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    System.out.println("output.close();");
                    output.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }
    }).start();

    return output;
}

最佳答案

形成 Jersey 文档:

使用 ChunkedOutput 写入 block 很简单,您只需调用方法 write() 即可将一个 block 写入输出。对于输入读数,它稍微复杂一些。除非开发人员告知,否则 ChunkedInput 不知道如何区分字节流中的 block 。为了定义自定义 block 边界,ChunkedInput 提供了注册 ChunkParser 的可能性,它从输入流中读取 block 并将它们分开。 Jersey 提供了几个 block 解析器实现,如果需要,您可以实现自己的解析器来分离您的 block 。在我们上面的示例中,使用了 Jersey 提供的默认解析器,它根据是否存在\r\n 定界字符序列 来分隔 block 。

所以你的服务器必须用\r\n 分隔 block ,或者你必须注册一个 ChunkParser。

假设你有一个恒定的最终确定你可以尝试的每个 block :

Client client = ClientBuilder.newClient();
//2 is to increase amount of data and 3(seconds) is for time b/w chunked output  ,can be changed
        final Response response = client.target("http://jerseyexample-ravikant.rhcloud.com/rest/jws/streaming/2/3").request()
                .get();
        final ChunkedInput<String> chunkedInput = response.readEntity(new GenericType<ChunkedInput<String>>() {
        });
        chunkedInput.setParser(ChunkedInput.createParser(BOUNDARY));
        String chunk;
        while ((chunk = chunkedInput.read()) != null) {
            System.err.println("Next chunk received: " );
            System.out.println(chunk);
        }

而 BOUNDARY 是每个 block 的最终字符串。 您编辑中的 in.readLine 解决方案将按每个换行符分解“ block ”,即使一个 block 包含\n,它也会被解释为 2 个 block 。

关于java - ChunkedInput 在 Jersey 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41483716/

相关文章:

json - 未找到 Java 类型类 net.sf.json.JSONObject 和 MIME 媒体类型 application/json 的消息正文编写器

JAVA API,JERSEY/POST 不工作

java - AspectJ:如何记录方法的成功完成?

java - ECDSA 使用 HSM 签名并在 Java/Kotlin 中验证

java - 如何更新 Firebase 数据库

java - Azure 存储服务 REST API : Create Container

rest - 在领域驱动设计中可以调用另一个限界上下文的应用程序服务吗?

php - 如何在PHP中使用curl获取数据?

java - 带有 javax.ws.rs.core.Application 的 MultiPartFeature

java - 链式哈希 VS 双重探测