ChunkedInput not working in jersey

假装没事ソ 提交于 2019-12-01 21:26:36

问题


Can anyone help me why the java code is having issue and printing all data in one go instead of prinitng each chunk as javascript code

Java Code :

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 : (Open Page http://jerseyexample-ravikant.rhcloud.com/rest/jws and then press F12 and run below in console as javascript call not allowed from other domain)

//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()

EDIT : Just for help it also works will normal java connection

        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();

My WebService Code

@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;
}

回答1:


Form jersey docs:

Writing chunks with ChunkedOutput is simple, you only call method write() which writes exactly one chunk to the output. With the input reading it is slightly more complicated. The ChunkedInput does not know how to distinguish chunks in the byte stream unless being told by the developer. In order to define custom chunks boundaries, the ChunkedInput offers possibility to register a ChunkParser which reads chunks from the input stream and separates them. Jersey provides several chunk parser implementation and you can implement your own parser to separate your chunks if you need. In our example above the default parser provided by Jersey is used that separates chunks based on presence of a \r\n delimiting character sequence.

So your server has to separate chunks with \r\n, or you have to register a ChunkParser.

Assuming you have a constant finalising each chunk you could try:

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);
        }

While BOUNDARY is a finalizing string for each chunk. The in.readLine solution in your edit will break down "chunks" by every newline, even if one chunk consist a \n, it will be interpreted as 2 chunks.



来源:https://stackoverflow.com/questions/41483716/chunkedinput-not-working-in-jersey

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!