users@jersey.java.net

[Jersey] Re: What is the difference between returning a InputStream and StreamingOuput objects as a Response body?

From: Miroslav Fuksa <miroslav.fuksa_at_oracle.com>
Date: Mon, 9 Dec 2013 16:58:45 +0100

Hi,

if you return InputStream, there is an internal provider in Jersey that reads bytes from your InputStream and writes data to the response OutputStream (similar logic that you have in your implementation of StreamingOutput but does not use nio). So, in your case I would use the first method that just returns InputStream. However, if you need to make more complex logic and not just pass data from one InputStream into the OutputStream you can use StreamingOutput. Or better: you will implement the logic into your custom MessageBodyWriter where you can also manipulate http headers.

Mira


On Dec 5, 2013, at 6:19 PM, Andrew Chillrud <achillrud_at_opentext.com> wrote:

> I am implementing a resource that returns file content as a stream. The resource method calls a third party library that returns an InputStream and the Mimetype of the requested file. Initially I was just return the InputStream as the Response body. However in searching the web it appears that returning a StreamingOutput object seems to be the more common approach. I have implemented this approach as well, but it is not clear to me what the difference in behavior between these two approaches will be. Can anyone explain this?
>
> @Path("/contentasinputstream/{id}")
> @GET
> public Response getContentAsInputStream(@PathParam("id") String id)
> {
> try
> {
> ContentInfo contentInfo = new ContentManager().retrieveContentInfo(id);
> }
> catch (Throwable t)
> {
> throw new WebApplicationException(t);
> }
>
> return Response.ok(contentInfo.getInputStream()).type(contentInfo.getMimeType()).build();
> }
>
> @Path("/contentasstreamingoutput/{id}")
> @GET
> public Response getContentAsStreamingOutput(@PathParam("id") String id)
> {
> try
> {
> ContentInfo contentInfo = new ContentManager().retrieveContentInfo(id);
> }
> catch (Throwable t)
> {
> throw new WebApplicationException(t);
> }
>
> final InputStream is = contentInfo.getInputStream();
>
> StreamingOutput stream = new StreamingOutput()
> {
> @Override
> public void write(OutputStream os) throws IOException, WebApplicationException
> {
> ReadableByteChannel source = null;
> WritableByteChannel destination = null;
>
> try
> {
> source = Channels.newChannel(is);
> destination = Channels.newChannel(os);
>
> ByteBuffer byteBuffer = ByteBuffer.allocateDirect(CHUNK_SIZE);
> while (source.read(byteBuffer) != -1)
> {
> byteBuffer.flip();
> destination.write(byteBuffer);
> byteBuffer.clear();
> }
>
> os.flush();
> }
> catch (IOException e)
> {
> throw new WebApplicationException(t);
> }
> finally
> {
> IOUtils.closeQuietly(is);
> IOUtils.closeQuietly(os);
>
> try
> {
> if (source != null)
> source.close();
> if (destination != null)
> destination.close();
> }
> catch (IOException e)
> {
> log.error(e);
> }
> }
> }
> };
>
> return Response.ok(stream).type(contentInfo.getMimeType()).build();
> }