All pastes #764707 Raw Edit

Something

public text v1 · immutable
·published 2007-11-07 14:26 UTC
rendered paste body
package fr.cvf.vodoo.zne.web.view;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.web.servlet.View;

/**
 * <p>
 * A View that allows to pass a stream directly to the browser. Very useful to serve files, or serve
 * specific content (JSON, etc..)
 * </p>
 * <p> The model MUST have an {@link StreamView#INPUT_STREAM_KEY} "key" that resolves to some {@link InputStream} instance. 
 * </p>
 * <p>
 * Ported from Struts2 StreamResult.
 * </p>
 */
public class StreamView implements View {

    public static final String INPUT_STREAM_KEY = "inputStream";
    
    /** The Constant logger. */
    private final static Logger logger = Logger.getLogger(StreamView.class);

    /** The buffer size. */
    protected int bufferSize = 1024;

    /** The content length. */
    protected int contentLength = -1;

    /** The content type. */
    protected String contentType;

    /** The content disposition. */
    protected String contentDisposition = "inline";

    /**
     * Instantiates a new stream view.
     * 
     * @param contentType the content type
     * @param inputStream the input stream
     */
    public StreamView(String contentType) {
        super();

        if (contentType == null) {
            throw new IllegalArgumentException("Content Type cannot be null");
        }

        this.contentType = contentType;
    }

    /**
     * (non-Javadoc)
     * 
     * @see org.springframework.web.servlet.View#getContentType()
     */
    public String getContentType() {
        return this.contentType;
    }

    /**
     * Sets the content type.
     * 
     * @param contentType The contentType to set.
     */
    public void setContentType(String contentType) {
        this.contentType = contentType;
    }

    /**
     * Gets the buffer size.
     * 
     * @return Returns the bufferSize.
     */
    public int getBufferSize() {
        return this.bufferSize;
    }

    /**
     * Sets the buffer size.
     * 
     * @param bufferSize The bufferSize to set.
     */
    public void setBufferSize(int bufferSize) {
        this.bufferSize = bufferSize;
    }

    /**
     * Gets the content length.
     * 
     * @return Returns the contentLength.
     */
    public int getContentLength() {
        return this.contentLength;
    }

    /**
     * Sets the content length.
     * 
     * @param contentLength The contentLength to set.
     */
    public void setContentLength(int contentLength) {
        this.contentLength = contentLength;
    }

    /**
     * Gets the content disposition.
     * 
     * @return Returns the Content-disposition header value.
     */
    public String getContentDisposition() {
        return this.contentDisposition;
    }

    /**
     * Sets the content disposition.
     * 
     * @param contentDisposition the Content-disposition header value to use.
     */
    public void setContentDisposition(String contentDisposition) {
        this.contentDisposition = contentDisposition;
    }

    /**
     * (non-Javadoc)
     * 
     * @see org.springframework.web.servlet.View#render(java.util.Map,
     *      javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    @SuppressWarnings("unchecked")
    public void render(Map map, HttpServletRequest request, HttpServletResponse response) throws Exception {
        
        /** The input stream. */
        InputStream inputStream = (InputStream) map.get(INPUT_STREAM_KEY);

        if (inputStream == null) {
            throw new IllegalArgumentException("Input Stream cannot be null");
        }
        
        OutputStream oOutput = null;

        try {
            // Find the Response in context
            HttpServletResponse oResponse = response;

            // Set the content type
            oResponse.setContentType(this.contentType);

            // Set the content length
            if (this.contentLength >= 0) {
                oResponse.setContentLength(this.contentLength);
            }

            // Set the content-disposition
            if (this.contentDisposition != null) {
                oResponse.addHeader("Content-disposition", this.contentDisposition);
            }

            // Get the outputstream
            oOutput = oResponse.getOutputStream();

            if (StreamView.logger.isDebugEnabled()) {
                StreamView.logger.debug("Streaming result ["
                        + "inputStream"
                        + "] type=["
                        + this.contentType
                        + "] length=["
                        + this.contentLength
                        + "] content-disposition=["
                        + this.contentDisposition
                        + "]");
            }

            // Copy input to output
            StreamView.logger.debug("Streaming to output buffer +++ START +++");
            byte[] oBuff = new byte[this.bufferSize];
            int iSize;
            while (-1 != (iSize = inputStream.read(oBuff))) {
                oOutput.write(oBuff, 0, iSize);
            }
            StreamView.logger.debug("Streaming to output buffer +++ END +++");

            // Flush
            oOutput.flush();
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
            if (oOutput != null) {
                oOutput.close();
            }
        }
    }

}