Low Level Streaming with JAX-RS StreamingOutput
When working with large data or files, it is recommended to stream the output rather than loading the entire response into memory. This helps protect the servers resources and avoids getting out of memory exceptions. The JAX-RS StreamingOutput
class is a simple callback that can be implemented to send the entity in the response when the application wants to stream the output.
JAX-RS StreamingOutput Example
We create a new StreamingOutput
using an anonymous inner class and override the write()
method. Using this method we can write directly to the OutputStream
. This example streams all numbers from 1 to 9999999. When this service is called, it’ll stream the response when the output stream is available.
package com.memorynotfound.rs;
import javax.ws.rs.*;
import javax.ws.rs.core.*;
import java.io.*;
@Path("/numbers")
public class NumbersResource {
@GET
public Response streamExample(){
StreamingOutput stream = new StreamingOutput() {
@Override
public void write(OutputStream out) throws IOException, WebApplicationException {
Writer writer = new BufferedWriter(new OutputStreamWriter(out));
for (int i = 0; i < 10000000 ; i++){
writer.write(i + " ");
}
writer.flush();
}
};
return Response.ok(stream).build();
}
}
Demo
URL: http://localhost:8081/jaxrs-streaming/api/orders
Hi, Thanks for sharing the post. I tried small variation by adding delay in writing numbers to StreamingOutput, However the output starts printing only after all 60 numbers are written. I was expecting one number to be printed at a time. Tried the cURL but same issue.
Writer writer = new BufferedWriter(new OutputStreamWriter(out));
for (int i = 0; i < 60 ; i++){
writer.write(i + ” “);
writer.flush(); // Shifted this inside.
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
//eat up for demo purpose
}
}