users@jersey.java.net

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

From: Andrew Chillrud <achillrud_at_opentext.com>
Date: Thu, 5 Dec 2013 17:19:48 +0000

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