Java tutorial
/* * Copyright (c) 2007 NTT DATA Corporation * * 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 jp.terasoluna.fw.web.struts.actions; import java.beans.PropertyDescriptor; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Method; import java.net.SocketException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Map.Entry; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import jp.terasoluna.fw.exception.SystemException; import org.apache.commons.fileupload.util.Streams; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.BeanWrapper; import org.springframework.beans.BeanWrapperImpl; /** * t@C_E??[h?s?[eBeBNX?B * <p> * <h5>_E??[ht@CGR?[fBO?X</h5> * _E??[hwt@C?iuEU?\t@C?j * GR?[fBOftHgInternet Explorer?B * GR?[fBO?X?A{@link DownloadFileNameEncoder}NX * ???ABean`t@C??sKv?B * * <h5><code>DownloadFileNameEncoder</code></h5> * <code>User-Agent</code>uEU?A * FireFox??commons-codecNXpGR?[fBO?s?B * <pre><code> * public class MyEncoder implements DownloadFileNameEncoder { * * public String encode(String original, HttpServletRequest request, * HttpServletResponse response) { * String userAgent = request.getHeader("User-Agent"); * if (StringUtils.contains(userAgent, "MSIE")) { * return encodeForIE(original); * } else if (StringUtils.contains(userAgent, "Gecko")) { * return encodeForGecko(original); * } * return encodeForIE(original); * } * * protected String encodeForGecko(String original) { * try { * return new BCodec().encode(original); * } catch (EncoderException e) { * return original; * } * } * * protected String encodeForIE(String original) { * try { * return URLEncoder.encode(original, * AbstractDownloadObject.DEFAULT_CHARSET); * } catch (UnsupportedEncodingException e) { * return original; * } * } * } * </code></pre> * * <h5>Bean`t@C?</h5> * <pre><code> * <bean class="jp.terasoluna.fw.web.struts.actions.FileDownloadUtil"> * <property name="encoder" ref="encoder"/> * </bean> * <bean name="encoder" class="sample.MyEncoder"/> * </code></pre> */ public class FileDownloadUtil { /** * ?ONX?B */ private final static Log log = LogFactory.getLog(FileDownloadUtil.class); /** * X|X<code>CONTENT-DISPOSITION</code>wb_?B */ public static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition"; /** * _E??[h?CX^X1???G?[R?[h?B */ public static final String TOO_MANY_DOWNLOAD_ERROR = "errors.too.many.download"; /** * wt@CGR?[_?B */ protected static DownloadFileNameEncoder encoder = new DownloadFileNameEncoderImpl(); /** * wt@CGR?[_??B * * @param encoder wt@CGR?[_?B */ public void setEncoder(DownloadFileNameEncoder encoder) { if (encoder == null) { throw new IllegalArgumentException("encoder must not be null."); } FileDownloadUtil.encoder = encoder; } /** * uEU_E??[h?B * * @param result _E??[hf?[^?CX^X?B * @param request NGXg?B * @param response X|X?B */ @SuppressWarnings("unchecked") public static void download(Object result, HttpServletRequest request, HttpServletResponse response) { List<AbstractDownloadObject> downloadList = new ArrayList<AbstractDownloadObject>(); if (result instanceof AbstractDownloadObject) { downloadList.add((AbstractDownloadObject) result); } else { BeanWrapper wrapper = new BeanWrapperImpl(result); PropertyDescriptor[] propertyDescriptors = wrapper.getPropertyDescriptors(); for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { Method readMethod = propertyDescriptor.getReadMethod(); if (readMethod == null) { continue; } Class type = readMethod.getReturnType(); if (AbstractDownloadObject.class.isAssignableFrom(type)) { downloadList .add((AbstractDownloadObject) wrapper.getPropertyValue(propertyDescriptor.getName())); } } } if (downloadList.isEmpty()) { return; } // _E??[hIuWFNg???O if (downloadList.size() != 1) { throw new SystemException(new IllegalStateException("Too many AbstractDownloadObject properties."), TOO_MANY_DOWNLOAD_ERROR); } try { download(downloadList.get(0), request, response, true); } catch (SocketException e) { if (log.isDebugEnabled()) { log.debug(e.getMessage(), e); } } catch (IOException e) { if (log.isErrorEnabled()) { log.error("IOException has occurred while downloading", e); } } } /** * uEU_E??[h?B * @param downloadObject _E??[h??B * @param request NGXg?B * @param response X|X?B * * @throws IOException _E??[h?oO????B */ public static void download(AbstractDownloadObject downloadObject, HttpServletRequest request, HttpServletResponse response, boolean forceDownload) throws IOException { // downloadObjectnull???A?? if (downloadObject == null) { if (log.isWarnEnabled()) { log.warn("No download object."); } return; } // wb_??B Map<String, List<String>> additionalHeaders = downloadObject.getAdditionalHeaders(); // wb_?null???A?? if (additionalHeaders == null) { if (log.isWarnEnabled()) { log.warn("Header must not be null."); } return; } // wb_??B Set<Entry<String, List<String>>> entrySet = additionalHeaders.entrySet(); for (Entry<String, List<String>> entry : entrySet) { String headerName = entry.getKey(); List<String> headerValues = entry.getValue(); // wb_?L?[lXgnull???A?? if (headerValues == null || headerName == null) { if (log.isWarnEnabled()) { log.warn("Header name and value must not be null."); } return; } for (String headerValue : headerValues) { // wb_?lnull if (headerValue == null) { headerValue = ""; } response.addHeader(headerName, headerValue); } } // GR?[fBO? String charSet = downloadObject.getCharset(); if (StringUtils.isNotEmpty(charSet)) { response.setCharacterEncoding(downloadObject.getCharset()); } // Reg^Cv? String contentType = downloadObject.getContentType(); if (StringUtils.isNotEmpty(contentType)) { response.setContentType(downloadObject.getContentType()); } // f?[^TCY? int contentLength = downloadObject.getLengthOfData(); if (contentLength > 0) { response.setContentLength(downloadObject.getLengthOfData()); } // t@C????A??B // ?????B String name = downloadObject.getName(); if (name != null) { name = encoder.encode(name, request, response); } else { name = encoder.encode("", request, response); } setFileName(response, name, forceDownload); InputStream inputStream = downloadObject.getStream(); OutputStream outputStream = null; try { // _E??[h???s outputStream = response.getOutputStream(); Streams.copy(inputStream, outputStream, false); } finally { if (inputStream != null) { inputStream.close(); } if (outputStream != null) { outputStream.flush(); outputStream.close(); } } } /** * t@C? * * @param response X|X?B * @param name _E??[h?B * @param forceDownload ?_E??[h?B<code>true</code>???A??B */ protected static void setFileName(HttpServletResponse response, String name, boolean forceDownload) { if (forceDownload) { // LbV?IE? String contentDispositionValue = "attachment;" + " filename=" + name; response.setHeader(HEADER_CONTENT_DISPOSITION, contentDispositionValue); } else { String contentDispositionValue = "inline; filename=" + name; response.setHeader(HEADER_CONTENT_DISPOSITION, contentDispositionValue); } } }