NIO Extension
Introduction
Servlet 3.1 API introduces a support for Non-Blocking IO, see this tutorial for more information.
The idea is that when the service code reads or writes the stream it does not block at all and only does a read or write action when a servlet container is ready to handle it effectively.
Early JAX-RS 2.1 API had a server-side prototype to help the JAX-RS service code utilize this Servlet 3.1 NIO features in a JAX-RS friendly way. Unfortunately that prototype was dropped from the final 2.1 API with the future major JAX-RS version expected to provide a much more complete and sophisticated NIO API.
CXF 3.2.0 has retained the implementation of the original JAX-RS 2.1 NIO API prototype and made it possible for the users to experiment with it.
NIO Read
@POST @Consumes(MediaType.TEXT_PLAIN) @Produces(MediaType.TEXT_PLAIN) public void uploadBookStream(@Suspended AsyncResponse response) { final ByteArrayOutputStream out = new ByteArrayOutputStream(); final byte[] buffer = new byte[4096]; final LongAdder adder = new LongAdder(); new NioReadEntity( // read handler in -> { final int n = in.read(buffer); if (n > 0) { adder.add(n); out.write(buffer, 0, n); } }, // completion handler () -> { closeOutputStream(out); response.resume("Book Store uploaded: " + adder.longValue() + " bytes"); } // by default the runtime will resume AsyncResponse with Throwable itself // if the error handler is not provided //, // error handler //t -> { // response.resume(t); //} ); }
NIO Write
@GET @Produces(MediaType.TEXT_PLAIN) public Response getBookStream() throws IOException { final ByteArrayInputStream in = new ByteArrayInputStream( IOUtils.readBytesFromStream(getClass().getResourceAsStream("/files/books.txt"))); final byte[] buffer = new byte[4096]; return Response.ok().entity( new NioWriteEntity( out -> { final int n = in.read(buffer); if (n >= 0) { out.write(buffer, 0, n); return true; } closeInputStream(in); return false; } // by default the runtime will throw the exception itself // if the error handler is not provided //, //throwable -> { // throw throwable; //} )) .build(); }
Even Easier NIO Write
import org.apache.cxf.annotations.UseNio; @GET @Produces(MediaType.TEXT_PLAIN) @Path("/is") @UseNio public InputStream getBookStreamFromInputStream() throws IOException { return getClass().getResourceAsStream("/files/books.txt"); }