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