36. Streaming binary content

PROBLEM

Many web applications need to stream binary content that is either stored in a database or generated dynamically. As demonstrated in the Implementing File Upload for Spring MVC and Implementing File Upload for Spring Web Flow recipes, binary content can be uploaded to a web application. The binary content will typically also need to be displayed or be downloaded. For example if you are uploading pictures to store them in a database, then you will likely need to render the photos in the web application using the img tag. If you are uploading documents to store them in a database, you will likely need to download the documents using an html anchor. In both cases you need a way to stream binary content.

SOLUTION

In order to facilitate the streaming of binary content in a Spring web application, Skyway Builder automatically registers a view that contains logic for streaming binary content to a browser.

HOW IT WORKS

The view is automatically registered under the id of streamedBinaryContentView with the class of org.execution.web.binary.ModelAttributeStreamer (open source: Apache license) in the web context file.

Example 2.43. Spring Context file - projectName-generated-web-context.xml

<bean id="streamedBinaryContentView" class="org.execution.web.binary.ModelAttributeStreamer" />

Setting the view for a URL mapping to streamedBinaryContentView will enable the output of the operation (domain object) to be streamed to the web browser. When accessing a URL that is mapped to the streamedBinaryContentView, there are some URL parameters that will dictate which attributes of the output domain object should be interpretted as the content, filename, and content type.

Table 2.6. URL parameters for streamedBinaryContentView

ParameterDescription
__varpathReference to the field that contains the actual byte array that should be streamed (i.e. __varpath=photo.content)
__filenameReference to the field that contains the filename (i.e. __filename=photo.filename)
__contenttypeReference to the field that contains the content type (i.e. __contenttype=photo.contentType)

Here's an example of streaming an image.

Example 2.44. Image Streaming Example - output only

<img src="${pageContext.request.contextPath}/getImage.html1?id=$__varpath=photo.content2
                                                              &__filename=photo.filename3
                                                              &__contenttype=photo.contentType">4

1

The URL (/getImage.html) is mapped to a controller method that outputs a domain object called photo. The view for the URL mapping is configured to streamedBinaryContentView.

2

The URL parameter __varpath specifies that the content field contains the byte array that should be streamed.

3

The URL parameter __filename specifies that the filename field contains the filename.

4

The URL parameter __contenttype specifies that the contentType field contains the content type.

If your controller method (operation) has an input variable that's needed for loading or generating the binary content, you can specify additional URL parameters corresponding to the input parameters. For example the operation may contain an input variable called id (type=text) that is used as the key for loading a photo from the database that should be streamed to the browser.

Example 2.45. Image Streaming Example - with inputs

<img src="${pageContext.request.contextPath}/getImage.html?id=${photo.id}
                                                              &__varpath=photo.content
                                                              &__filename=photo.filename
                                                              &__contenttype=photo.contentType">

If your application is generating documents or storing documents in a database, you may want to let the end-user download the documents. The following example shows how you can link to streamed binary content by specifying a streaming URL for the href of an html anchor.

Example 2.46. Document Streaming Example - with inputs

<a href="${pageContext.request.contextPath}/getDocument.html?id=${doc.id}
                                                              &__varpath=doc.content
                                                              &__filename=doc.filename
                                                              &__contenttype=doc.contentType">Download</a>

RELATED RECIPES

  1. Implementing File Upload for Spring Web Flow

  2. Implementing File Upload for Spring MVC