com.discovery.darchrow.http.ResponseUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.discovery.darchrow.http.ResponseUtil.java

Source

/*
 * Copyright (C) 2008 feilong (venusdrogon@163.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.discovery.darchrow.http;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Date;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.discovery.darchrow.date.DateExtensionUtil;
import com.discovery.darchrow.http.entity.HttpHeaders;
import com.discovery.darchrow.io.FileUtil;
import com.discovery.darchrow.io.IOWriteUtil;
import com.discovery.darchrow.io.MimeType;
import com.discovery.darchrow.io.MimeTypeUtil;
import com.discovery.darchrow.io.UncheckedIOException;
import com.discovery.darchrow.lang.CharsetType;
import com.discovery.darchrow.lang.StringUtil;
import com.discovery.darchrow.net.URIUtil;
import com.discovery.darchrow.util.Validator;

/**
 * {@link javax.servlet.http.HttpServletResponse} .
 *
 * @author <a href="mailto:venusdrogon@163.com"></a>
 * @version 1.0 2011-11-3 ?02:26:14
 * @see javax.servlet.http.HttpServletResponse
 * @since 1.0.0
 */
public final class ResponseUtil {

    /** The Constant log. */
    private static final Logger log = LoggerFactory.getLogger(ResponseUtil.class);

    /** Don't let anyone instantiate this class. */
    private ResponseUtil() {
        //AssertionError?. ?????. ???.
        //see Effective Java 2nd
        throw new AssertionError("No " + getClass().getName() + " instances for you!");
    }

    /**
     * ( contentType=application/force-download) .
     *
     * @param saveFileName
     *            ???, Content-Disposition header 
     * @param inputStream
     *            ???
     * @param contentLength
     *            ?????
     * @param request
     *            ? ?request? log
     * @param response
     *            response
     * @throws IOException
     *             the IO exception
     * @see IOWriteUtil#write(InputStream, OutputStream)
     * @see "org.springframework.http.MediaType"
     */
    public static void download(String saveFileName, InputStream inputStream, Number contentLength,
            HttpServletRequest request, HttpServletResponse response) throws IOException {
        //?
        String contentType = null;
        String contentDisposition = null;
        download(saveFileName, inputStream, contentLength, contentType, contentDisposition, request, response);
    }

    /**
     * .
     *
     * @param saveFileName
     *            ???, Content-Disposition header 
     * @param inputStream
     *            ???
     * @param contentLength
     *            ?????
     * @param contentType
     *            the content type
     * @param contentDisposition
     *            the content disposition
     * @param request
     *            ? ?request? log
     * @param response
     *            response
     * @throws IOException
     *             the IO exception
     * @see IOWriteUtil#write(InputStream, OutputStream)
     * @see "org.springframework.http.MediaType"
     * @see "org.apache.http.HttpHeaders"
     * @see "org.springframework.http.HttpHeaders"
     * @see MimeTypeUtil#getContentTypeByFileName(String)
     * @see javax.servlet.ServletContext#getMimeType(String)
     */
    public static void download(String saveFileName, InputStream inputStream, Number contentLength,
            String contentType, String contentDisposition, HttpServletRequest request, HttpServletResponse response)
            throws IOException {

        setDownloadResponseHeader(saveFileName, contentLength, contentType, contentDisposition, response);

        //**********************************?********************************************************************
        downLoadData(saveFileName, inputStream, contentLength, request, response);
    }

    /**
     * Down load data.
     *
     * @param saveFileName
     *            the save file name
     * @param inputStream
     *            the input stream
     * @param contentLength
     *            the content length
     * @param request
     *            the request
     * @param response
     *            the response
     * @throws UncheckedIOException
     *             the unchecked io exception
     */
    private static void downLoadData(String saveFileName, InputStream inputStream, Number contentLength,
            HttpServletRequest request, HttpServletResponse response) throws UncheckedIOException {
        Date beginDate = new Date();

        if (log.isInfoEnabled()) {
            log.info("begin download~~,saveFileName:[{}],contentLength:[{}]", saveFileName,
                    FileUtil.formatSize(contentLength.longValue()));
        }
        try {
            OutputStream outputStream = response.getOutputStream();

            //? 
            //inputStream.read(buffer);
            //outputStream = new BufferedOutputStream(response.getOutputStream());
            //outputStream.write(buffer);

            IOWriteUtil.write(inputStream, outputStream);
            if (log.isInfoEnabled()) {
                Date endDate = new Date();
                log.info("end download,saveFileName:[{}],contentLength:[{}],time use:[{}]", saveFileName,
                        FileUtil.formatSize(contentLength.longValue()),
                        DateExtensionUtil.getIntervalForView(beginDate, endDate));
            }
        } catch (IOException e) {
            /*
             * ?  ClientAbortException  ????? 
             * ?? ??
             * ???????
             * ? KILL? ?? ClientAbortException
             */
            //ClientAbortException:  java.net.SocketException: Connection reset by peer: socket write error
            final String exceptionName = e.getClass().getName();

            if (StringUtil.isContain(exceptionName, "ClientAbortException")
                    || StringUtil.isContain(e.getMessage(), "ClientAbortException")) {
                log.warn(
                        "[ClientAbortException],maybe user use Thunder soft or abort client soft download,exceptionName:[{}],exception message:[{}] ,request User-Agent:[{}]",
                        exceptionName, e.getMessage(), RequestUtil.getHeaderUserAgent(request));
            } else {
                log.error("[download exception],exception name: " + exceptionName, e);
                throw new UncheckedIOException(e);
            }
        }
    }

    /**
     *  download response header.
     *
     * @param saveFileName
     *            the save file name
     * @param contentLength
     *            the content length
     * @param contentType
     *            the content type
     * @param contentDisposition
     *            the content disposition
     * @param response
     *            the response
     */
    private static void setDownloadResponseHeader(String saveFileName, Number contentLength, String contentType,
            String contentDisposition, HttpServletResponse response) {
        //**********************************************************************************************
        // response
        //getResponsegetWriter()?????response.resetresetBuffer
        //getOutputStream() has already been called for this response
        //jsp??,response.getOutputStream()??java.lang.IllegalStateException:getOutputStream() has already been called for this response,Exception
        response.reset();

        // ===================== Default MIME Type Mappings =================== -->
        //See tomcat web.xml
        //When serving static resources, Tomcat will automatically generate a "Content-Type" header based on the resource's filename extension, based on these mappings.  
        //Additional mappings can be added here (to apply to all web applications), or in your own application's web.xml deployment descriptor.                                               -->

        if (Validator.isNullOrEmpty(contentType)) {
            contentType = MimeTypeUtil.getContentTypeByFileName(saveFileName);

            if (Validator.isNullOrEmpty(contentType)) {
                //contentType = "application/force-download";//,phpapplication/force-download,??HTTP ????
                //application/x-download

                //.* ???   application/octet-stream
                contentType = MimeType.BIN.getMime();
                //The HTTP specification recommends setting the Content-Type to application/octet-stream. 
                //Unfortunately, this causes problems with Opera 6 on Windows (which will display the raw bytes for any file whose extension it doesn't recognize) and on Internet Explorer 5.1 on the Mac (which will display inline content that would be downloaded if sent with an unrecognized type).
            }
        }

        //??????????????
        if (Validator.isNotNullOrEmpty(contentType)) {
            response.setContentType(contentType);
        }

        //?:??,?,.???
        //????????
        //response.setBufferSize(10240);

        //see org.apache.commons.io.IOUtils.copyLarge(InputStream, OutputStream) javadoc
        //This method buffers the input internally, so there is no need to use a BufferedInputStream

        //****************************************************************************************************

        //Content-Disposition takes one of two values, `inline' and  `attachment'.  
        //'Inline' indicates that the entity should be immediately displayed to the user, 
        //whereas `attachment' means that the user should take additional action to view the entity.
        //The `filename' parameter can be used to suggest a filename for storing the bodypart, if the user wishes to store it in an external file.
        if (Validator.isNullOrEmpty(contentDisposition)) {
            // ?
            contentDisposition = "attachment; filename=" + URIUtil.encode(saveFileName, CharsetType.UTF8);

        }
        //TODO ? httpcomponents httpcore  org.apache.http.HttpHeaders
        response.addHeader(HttpHeaders.CONTENT_DISPOSITION, contentDisposition);

        response.setContentLength(contentLength.intValue());
    }

    /**
     * ?.
     *
     * @param response
     *            HttpServletResponse
     * @param url
     *            
     * @throws UncheckedIOException
     *             the unchecked io exception
     */
    public static void setNoCacheAndRedirect(HttpServletResponse response, String url) throws UncheckedIOException {
        setNoCacheHeader(response);
        try {
            response.sendRedirect(url);
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

    /**
     * ??.
     *
     * @param response
     *            HttpServletResponse
     */
    public static void setNoCacheHeader(HttpServletResponse response) {
        // HTTP1.1? CacheControl = no-cache??
        // ? HTTP1.0 ?? Cache-Control 

        // ?? HTTP1.0 ?IEPragma:no-cache  HTTP???
        //  (https://)/??? Pragma:no-cache  Internet Explorer??
        // ?Pragma:no-cache ???? Expires:-1??
        response.setHeader(HttpHeaders.PRAGMA, "No-cache");

        // Cache-controlno-cache???Internet?
        response.setHeader(HttpHeaders.CACHE_CONTROL, "no-cache");

        //In other wordsExpires: 0not always leads to immediate resource expiration, 
        //therefore should be avoided andExpires: -1orExpires: [some valid date in the past]should be used instead.
        response.setDateHeader(HttpHeaders.EXPIRES, -1);
    }

    //    [start] PrintWriter

    /**
     * json?.
     *
     * @param response
     *            HttpServletResponse
     * @param json
     *            json
     * @see #write(HttpServletResponse, Object, String, String)
     * @since 1.0.9
     */
    public static void writeJson(HttpServletResponse response, Object json) {
        writeJson(response, json, CharsetType.UTF8);
    }

    /**
     * json?.
     *
     * @param response
     *            HttpServletResponse
     * @param json
     *            json
     * @param characterEncoding
     *            the character encoding
     * @see #write(HttpServletResponse, Object, String, String)
     * @since 1.0.9
     */
    public static void writeJson(HttpServletResponse response, Object json, String characterEncoding) {
        String contentType = MimeType.JSON.getMime() + ";charset=" + characterEncoding;
        write(response, json, contentType, characterEncoding);
    }

    /**
     * .
     *
     * @param response
     *            HttpServletResponse
     * @param content
     *            
     * @throws UncheckedIOException
     *             the unchecked io exception
     * @see javax.servlet.ServletResponse#getWriter()
     * @see java.io.PrintWriter#print(Object)
     * @see java.io.PrintWriter#flush()
     * @see #write(HttpServletResponse, Object, String, String)
     */
    public static void write(HttpServletResponse response, Object content) throws UncheckedIOException {
        String contentType = null;
        String characterEncoding = null;
        write(response, content, contentType, characterEncoding);
    }

    /**
     * .
     *
     * @param response
     *            HttpServletResponse
     * @param content
     *            
     * @param contentType
     *            the content type
     * @param characterEncoding
     *            the character encoding
     * @throws UncheckedIOException
     *             the unchecked io exception
     * @see javax.servlet.ServletResponse#getWriter()
     * @see java.io.PrintWriter#print(Object)
     * @see java.io.PrintWriter#flush()
     * @since 1.0.9
     */
    public static void write(HttpServletResponse response, Object content, String contentType,
            String characterEncoding) throws UncheckedIOException {
        try {
            //? ? getWriter?
            if (Validator.isNotNullOrEmpty(contentType)) {
                response.setContentType(contentType);
            }
            if (Validator.isNotNullOrEmpty(characterEncoding)) {
                response.setCharacterEncoding(characterEncoding);
            }

            PrintWriter printWriter = response.getWriter();
            printWriter.print(content);
            printWriter.flush();

            //http://www.iteye.com/problems/56543
            //tomcatjetty?? printWriter.close();
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

    // [end]
}