2016-12-24 2 views
0

Я пытаюсь передать поток ProcessBuilder через объект ответа. Сейчас я получаю вывод на своей стороне клиента только после завершения процесса. Я хотел бы, чтобы результат на стороне клиента печатался одновременно. В настоящее время это мой код, и после завершения процесса он распечатывает все на стороне клиента (POSTMAN).Как одновременно поток OutputStream через объект ответа Джерси

StreamingOutput stream = new StreamingOutput() { 
     @Override 
     public void write(OutputStream os) throws IOException, WebApplicationException { 
      String line; 
      Writer writer = new BufferedWriter(new OutputStreamWriter(os)); 
      BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream())); 
      try { 
       while ((line = input.readLine()) != null) { 
        writer.write("TEST"); 
        writer.write(line); 
        writer.flush(); 
        os.flush();; 
       } 
      } finally { 
       os.close(); 
       writer.close(); 
      }    
     } 
    }; 
    return Response.ok(stream).build(); 
+0

Посмотрите на это https://dzone.com/articles/jerseyjax-rs-streaming-json – gladiator

ответ

1

Что нужно, чтобы установить длину содержимого выходного буфера равным 0, так что трикотаж ничего не блокирует. Смотрите это более подробно: calling flush() on Jersey StreamingOutput has no effect

Вот это отдельное приложение Dropwizard, который демонстрирует это:

public class ApplicationReddis extends io.dropwizard.Application<Configuration>{ 

    @Override 
    public void initialize(Bootstrap<Configuration> bootstrap) { 
     super.initialize(bootstrap); 
    } 

    @Override 
    public void run(Configuration configuration, Environment environment) throws Exception { 
     environment.jersey().property(ServerProperties.OUTBOUND_CONTENT_LENGTH_BUFFER, 0); 
     environment.jersey().register(StreamResource.class); 
    } 

    public static void main(String[] args) throws Exception { 
     new ApplicationReddis().run("server", "/home/artur/dev/repo/sandbox/src/main/resources/config/test.yaml"); 
    } 

    @Path("test") 
    public static class StreamResource{ 

     @GET 
     public Response get() { 
      return Response.ok(new StreamingOutput() { 

       @Override 
       public void write(OutputStream output) throws IOException, WebApplicationException { 
        for(int i = 0; i < 100; i++) { 
         output.write(("Hello " + i + "\n").getBytes()); 
         output.flush(); 
         try { 
          Thread.sleep(100); 
         } catch (InterruptedException e) { 
          e.printStackTrace(); 
         } 
        } 
       } 
      }).build(); 
     } 
    } 

} 

Ничего часть Dropwizard, он просто использует майку под капотом.

environment.jersey().property(ServerProperties.OUTBOUND_CONTENT_LENGTH_BUFFER, 0); 

Эта часть устанавливает исходящую длину в 0. Это приведет к тому, что трикотаж не будет буферизовать что-либо.

Вам все равно необходимо очистить выходной поток в StreamingOutput, так как у него есть собственный буфер.

Запуск моего кода выше с Dropwizard 1.0.2 даст одну строку «привет» каждые 100 мс. Используя curl, я вижу, что весь вывод печатается немедленно.

Вы должны прочитать документацию и побочные эффекты установки OUTBOUND_CONTENT_LENGTH_BUFFER, чтобы убедиться, что вы не вводите нежелательные побочные эффекты.

+0

Спасибо, что решили мою проблему! – user1807948

Смежные вопросы