net.ymate.platform.webmvc.view.impl.BinaryView.java Source code

Java tutorial

Introduction

Here is the source code for net.ymate.platform.webmvc.view.impl.BinaryView.java

Source

/*
 * Copyright 2007-2016 the original author or authors.
 *
 * 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 net.ymate.platform.webmvc.view.impl;

import net.ymate.platform.core.lang.BlurObject;
import net.ymate.platform.core.lang.PairObject;
import net.ymate.platform.core.util.FileUtils;
import net.ymate.platform.webmvc.context.WebContext;
import net.ymate.platform.webmvc.util.MimeTypeUtils;
import net.ymate.platform.webmvc.view.AbstractView;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.Reader;
import java.net.URLEncoder;

/**
 * ??
 *
 * @author  (suninformation@163.com) on 2011-10-23 ?11:32:55
 * @version 1.0
 */
public class BinaryView extends AbstractView {

    private static final Log __LOG = LogFactory.getLog(BinaryView.class);

    protected String __fileName;
    protected Object __data;

    private long __length = -1;

    /**
     * @param targetFile 
     * @return ???NULL
     * @throws Exception ??
     */
    public static BinaryView bind(File targetFile) throws Exception {
        if (targetFile != null && targetFile.exists() && targetFile.isFile() && targetFile.canRead()) {
            BinaryView _binaryView = new BinaryView(targetFile);
            _binaryView.setContentType(MimeTypeUtils.getFileMimeType(FileUtils.getExtName(targetFile.getPath())));
            return _binaryView;
        }
        return null;
    }

    /**
     * 
     *
     * @param data ?
     */
    public BinaryView(Object data) {
        __data = data;
    }

    /**
     * 
     *
     * @param inputStream ??
     * @param length      ??
     */
    public BinaryView(InputStream inputStream, long length) {
        __data = inputStream;
        if (length > 0) {
            __length = length;
        }
    }

    protected void __doRenderView() throws Exception {
        HttpServletRequest _request = WebContext.getRequest();
        HttpServletResponse _response = WebContext.getResponse();
        //
        if (StringUtils.isNotBlank(__fileName)) {
            StringBuilder _dispositionSB = new StringBuilder("attachment;filename=");
            if (_request.getHeader("User-Agent").toLowerCase().contains("firefox")) {
                _dispositionSB.append(new String(__fileName.getBytes("UTF-8"), "ISO8859-1"));
            } else {
                _dispositionSB.append(URLEncoder.encode(__fileName, "UTF-8"));
            }
            _response.setHeader("Content-Disposition", _dispositionSB.toString());
        }
        //
        if (__data == null) {
            return;
        }
        // 
        if (__data instanceof File) {
            // ??
            __length = ((File) __data).length();
            // ?Range??
            PairObject<Long, Long> _rangePO = __doParseRange(__length);
            // 
            if (_rangePO != null) {
                __doSetRangeHeader(_response, _rangePO);
                // ?
                IOUtils.copyLarge(new FileInputStream((File) __data), _response.getOutputStream(),
                        _rangePO.getKey(), _rangePO.getValue());
            } else {
                // 
                _response.setContentLength(BlurObject.bind(__length).toIntValue());
                IOUtils.copyLarge(new FileInputStream((File) __data), _response.getOutputStream());
            }
        }
        // 
        else if (__data instanceof byte[]) {
            byte[] _datas = (byte[]) __data;
            _response.setContentLength(_datas.length);
            IOUtils.write(_datas, _response.getOutputStream());
        }
        // 
        else if (__data instanceof char[]) {
            char[] _datas = (char[]) __data;
            _response.setContentLength(_datas.length);
            IOUtils.write(_datas, _response.getOutputStream());
        }
        // ?
        else if (__data instanceof Reader) {
            Reader r = (Reader) __data;
            IOUtils.copy(r, _response.getOutputStream());
        }
        // ?
        else if (__data instanceof InputStream) {
            PairObject<Long, Long> _rangePO = __doParseRange(__length);
            if (_rangePO != null) {
                __doSetRangeHeader(_response, _rangePO);
                IOUtils.copyLarge((InputStream) __data, _response.getOutputStream(), _rangePO.getKey(),
                        _rangePO.getValue());
            } else {
                _response.setContentLength(BlurObject.bind(__length).toIntValue());
                IOUtils.copyLarge((InputStream) __data, _response.getOutputStream());
            }
        }
        // 
        else {
            String _content = StringUtils.trimToEmpty(BlurObject.bind(__data).toStringValue());
            _response.setContentLength(_content.length());
            IOUtils.write(_content, _response.getOutputStream());
        }
    }

    private void __doSetRangeHeader(HttpServletResponse response, PairObject<Long, Long> range) {
        // none???
        addHeader("Accept-Ranges", "bytes");
        // Content-Length: [?] - [?]
        long _totalLength = range.getValue() - range.getKey();
        addHeader("Content-Length", _totalLength + "");
        // Content-Range: bytes [?]-[? - 1]/[?]
        addHeader("Content-Range", "bytes " + range.getKey() + "-" + (range.getValue() - 1) + "/" + __length);
        // response.setHeader("Connection", "Close"); //??IE
        // Status: 206
        response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
    }

    /**
     * ?Range????
     *
     * @param length ??
     * @return ?null
     */
    private PairObject<Long, Long> __doParseRange(long length) {
        PairObject<Long, Long> _returnValue = null;
        // Range??
        String _rangeStr = WebContext.getRequest().getHeader("Range");
        if (_rangeStr != null && _rangeStr.startsWith("bytes=") && _rangeStr.length() >= 7) {
            _rangeStr = StringUtils.substringAfter(_rangeStr, "bytes=");
            String[] _ranges = StringUtils.split(_rangeStr, ",");
            // ?Range??...
            for (String _range : _ranges) {
                if (StringUtils.isBlank(_range)) {
                    return null;
                }
                // bytes=-100
                if (_range.startsWith("-")) {
                    long _end = Long.parseLong(_range);
                    long _start = length + _end;
                    if (_start < 0) {
                        return null;
                    }
                    _returnValue = new PairObject<Long, Long>(_start, length);
                    break;
                }
                // bytes=1024-
                if (_range.endsWith("-")) {
                    long _start = Long.parseLong(StringUtils.substringBefore(_range, "-"));
                    if (_start < 0) {
                        return null;
                    }
                    _returnValue = new PairObject<Long, Long>(_start, length);
                    break;
                }
                // bytes=10-1024
                if (_range.contains("-")) {
                    String[] _tmp = _range.split("-");
                    long _start = Long.parseLong(_tmp[0]);
                    long _end = Long.parseLong(_tmp[1]);
                    if (_start > _end) {
                        return null;
                    }
                    _returnValue = new PairObject<Long, Long>(_start, _end + 1);
                }
            }
        }
        return _returnValue;
    }

    /**
     * @param dispFileName ??
     * @return ?
     */
    public BinaryView useAttachment(String dispFileName) {
        __fileName = dispFileName;
        return this;
    }
}