Java tutorial
/* * 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; } }