CommonsMultipartResolver.java
上传用户:rifeng33
上传日期:2008-02-23
资源大小:20099k
文件大小:11k
源码类别:

Java编程

开发平台:

Java

  1. /*
  2.  * Copyright 2002-2004 the original author or authors.
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License");
  5.  * you may not use this file except in compliance with the License.
  6.  * You may obtain a copy of the License at
  7.  * 
  8.  *      http://www.apache.org/licenses/LICENSE-2.0
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software
  11.  * distributed under the License is distributed on an "AS IS" BASIS,
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  * See the License for the specific language governing permissions and
  14.  * limitations under the License.
  15.  */ 
  16. package org.springframework.web.multipart.commons;
  17. import java.io.File;
  18. import java.io.IOException;
  19. import java.io.UnsupportedEncodingException;
  20. import java.util.HashMap;
  21. import java.util.Iterator;
  22. import java.util.List;
  23. import java.util.Map;
  24. import javax.servlet.ServletContext;
  25. import javax.servlet.http.HttpServletRequest;
  26. import org.apache.commons.fileupload.DiskFileUpload;
  27. import org.apache.commons.fileupload.FileItem;
  28. import org.apache.commons.fileupload.FileUploadBase;
  29. import org.apache.commons.fileupload.FileUploadException;
  30. import org.apache.commons.logging.Log;
  31. import org.apache.commons.logging.LogFactory;
  32. import org.springframework.core.io.Resource;
  33. import org.springframework.util.StringUtils;
  34. import org.springframework.web.context.ServletContextAware;
  35. import org.springframework.web.multipart.MaxUploadSizeExceededException;
  36. import org.springframework.web.multipart.MultipartException;
  37. import org.springframework.web.multipart.MultipartHttpServletRequest;
  38. import org.springframework.web.multipart.MultipartResolver;
  39. import org.springframework.web.multipart.support.DefaultMultipartHttpServletRequest;
  40. import org.springframework.web.util.WebUtils;
  41. /**
  42.  * MultipartResolver implementation for
  43.  * <a href="http://jakarta.apache.org/commons/fileupload">Jakarta Commons FileUpload</a>.
  44.  *
  45.  * <p>Provides maximumFileSize, maximumInMemorySize, and headerEncoding settings as
  46.  * bean properties; see respective DiskFileUpload properties (sizeMax, sizeThreshold,
  47.  * headerEncoding) for details in terms of defaults and accepted values.
  48.  *
  49.  * <p>Saves temporary files to the servlet container's temporary directory.
  50.  * Needs to be initialized <i>either</i> by an application context <i>or</i>
  51.  * via the constructor that takes a ServletContext (for standalone usage).
  52.  *
  53.  * @author Trevor D. Cook
  54.  * @author Juergen Hoeller
  55.  * @since 29-Sep-2003
  56.  * @see #CommonsMultipartResolver(ServletContext)
  57.  * @see CommonsMultipartFile
  58.  * @see org.apache.commons.fileupload.DiskFileUpload
  59.  */
  60. public class CommonsMultipartResolver implements MultipartResolver, ServletContextAware {
  61. protected final Log logger = LogFactory.getLog(getClass());
  62. private DiskFileUpload fileUpload;
  63. private String defaultEncoding = WebUtils.DEFAULT_CHARACTER_ENCODING;
  64. private File uploadTempDir;
  65. /**
  66.  * Constructor for use as bean. Determines the servlet container's
  67.  * temporary directory via the ServletContext passed in as through the
  68.  * ServletContextAware interface (typically by a WebApplicationContext).
  69.  * @see #setServletContext
  70.  * @see org.springframework.web.context.ServletContextAware
  71.  * @see org.springframework.web.context.WebApplicationContext
  72.  */
  73. public CommonsMultipartResolver() {
  74. this.fileUpload = newFileUpload();
  75. }
  76. /**
  77.  * Constructor for standalone usage. Determines the servlet container's
  78.  * temporary directory via the given ServletContext.
  79.  * @param servletContext the ServletContext to use
  80.  */
  81. public CommonsMultipartResolver(ServletContext servletContext) {
  82. this();
  83. setServletContext(servletContext);
  84. }
  85. /**
  86.  * Initialize the underlying org.apache.commons.fileupload.DiskFileUpload instance.
  87.  * Can be overridden to use a custom subclass, e.g. for testing purposes.
  88.  * @return the new DiskFileUpload instance
  89.  */
  90. protected DiskFileUpload newFileUpload() {
  91. return new DiskFileUpload();
  92. }
  93. /**
  94.  * Return the underlying org.apache.commons.fileupload.DiskFileUpload instance.
  95.  * There is hardly any need to access this.
  96.  * @return the underlying DiskFileUpload instance
  97.  */
  98. public DiskFileUpload getFileUpload() {
  99. return fileUpload;
  100. }
  101. /**
  102.  * Set the maximum allowed size (in bytes) before uploads are refused.
  103.  * -1 indicates no limit (the default).
  104.  * @param maxUploadSize the maximum upload size allowed
  105.  * @see org.apache.commons.fileupload.FileUploadBase#setSizeMax
  106.  */
  107. public void setMaxUploadSize(long maxUploadSize) {
  108. this.fileUpload.setSizeMax(maxUploadSize);
  109. }
  110. /**
  111.  * Set the maximum allowed size (in bytes) before uploads are written to disk.
  112.  * Uploaded files will still be received past this amount, but they will not be
  113.  * stored in memory. Default is 10240, according to Commons FileUpload.
  114.  * @param maxInMemorySize the maximum in memory size allowed
  115.  * @see org.apache.commons.fileupload.DiskFileUpload#setSizeThreshold
  116.  */
  117. public void setMaxInMemorySize(int maxInMemorySize) {
  118. this.fileUpload.setSizeThreshold(maxInMemorySize);
  119. }
  120. /**
  121.  * Set the default character encoding to use for parsing requests,
  122.  * to be applied to headers of individual parts and to form fields.
  123.  * Default is ISO-8859-1, according to the Servlet spec.
  124.  * <p>If the request specifies a character encoding itself, the request
  125.  * encoding will override this setting. This also allows for generically
  126.  * overriding the character encoding in a filter that invokes the
  127.  * ServletRequest.setCharacterEncoding method.
  128.  * @param defaultEncoding the character encoding to use
  129.  * @see #determineEncoding
  130.  * @see javax.servlet.ServletRequest#getCharacterEncoding
  131.  * @see javax.servlet.ServletRequest#setCharacterEncoding
  132.  * @see WebUtils#DEFAULT_CHARACTER_ENCODING
  133.  * @see org.apache.commons.fileupload.FileUploadBase#setHeaderEncoding
  134.  */
  135. public void setDefaultEncoding(String defaultEncoding) {
  136. this.defaultEncoding = defaultEncoding;
  137. this.fileUpload.setHeaderEncoding(defaultEncoding);
  138. }
  139. /**
  140.  * Set the temporary directory where uploaded files get stored.
  141.  * Default is the servlet container's temporary directory for the web application.
  142.  * @see org.springframework.web.util.WebUtils#TEMP_DIR_CONTEXT_ATTRIBUTE
  143.  */
  144. public void setUploadTempDir(Resource uploadTempDir) throws IOException {
  145. if (!uploadTempDir.exists() && !uploadTempDir.getFile().mkdirs()) {
  146. throw new IllegalArgumentException("Given uploadTempDir [" + uploadTempDir +
  147.  "] could not be created");
  148. }
  149. this.uploadTempDir = uploadTempDir.getFile();
  150. this.fileUpload.setRepositoryPath(uploadTempDir.getFile().getAbsolutePath());
  151. }
  152. public void setServletContext(ServletContext servletContext) {
  153. if (this.uploadTempDir == null) {
  154. this.fileUpload.setRepositoryPath(WebUtils.getTempDir(servletContext).getAbsolutePath());
  155. }
  156. }
  157. public boolean isMultipart(HttpServletRequest request) {
  158. return FileUploadBase.isMultipartContent(request);
  159. }
  160. public MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) throws MultipartException {
  161. DiskFileUpload fileUpload = this.fileUpload;
  162. String enc = determineEncoding(request);
  163. // use prototype FileUpload instance if the request specifies
  164. // its own encoding that does not match the default encoding
  165. if (!enc.equals(this.defaultEncoding)) {
  166. fileUpload = new DiskFileUpload();
  167. fileUpload.setSizeMax(this.fileUpload.getSizeMax());
  168. fileUpload.setSizeThreshold(this.fileUpload.getSizeThreshold());
  169. fileUpload.setRepositoryPath(this.fileUpload.getRepositoryPath());
  170. fileUpload.setHeaderEncoding(enc);
  171. }
  172. try {
  173. List fileItems = fileUpload.parseRequest(request);
  174. Map parameters = new HashMap();
  175. Map multipartFiles = new HashMap();
  176. for (Iterator it = fileItems.iterator(); it.hasNext();) {
  177. FileItem fileItem = (FileItem) it.next();
  178. if (fileItem.isFormField()) {
  179. String value = null;
  180. try {
  181. value = fileItem.getString(enc);
  182. }
  183. catch (UnsupportedEncodingException ex) {
  184. logger.warn("Could not decode multipart item '" + fileItem.getFieldName() +
  185.             "] with encoding '" + enc + "': using platform default");
  186. value = fileItem.getString();
  187. }
  188. String[] curParam = (String[]) parameters.get(fileItem.getFieldName());
  189. if (curParam == null) {
  190. // simple form field
  191. parameters.put(fileItem.getFieldName(), new String[] { value });
  192. }
  193. else {
  194. // array of simple form fields
  195. String[] newParam = StringUtils.addStringToArray(curParam, value);
  196. parameters.put(fileItem.getFieldName(), newParam);
  197. }
  198. }
  199. else {
  200. // multipart file field
  201. CommonsMultipartFile file = new CommonsMultipartFile(fileItem);
  202. multipartFiles.put(file.getName(), file);
  203. if (logger.isDebugEnabled()) {
  204. logger.debug("Found multipart file [" + file.getName() + "] of size " + file.getSize() +
  205.              " bytes with original file name [" + file.getOriginalFilename() +
  206.              "], stored " + file.getStorageDescription());
  207. }
  208. }
  209. }
  210. return new DefaultMultipartHttpServletRequest(request, multipartFiles, parameters);
  211. }
  212. catch (FileUploadBase.SizeLimitExceededException ex) {
  213. throw new MaxUploadSizeExceededException(this.fileUpload.getSizeMax(), ex);
  214. }
  215. catch (FileUploadException ex) {
  216. throw new MultipartException("Could not parse multipart request", ex);
  217. }
  218. }
  219. /**
  220.  * Determine the encoding for the given request.
  221.  * Can be overridden in subclasses.
  222.  * <p>The default implementation checks the request encoding,
  223.  * falling back to the default encoding specified for this resolver.
  224.  * @param request current HTTP request
  225.  * @return the encoding for the request (never null)
  226.  * @see javax.servlet.ServletRequest#getCharacterEncoding
  227.  * @see #setDefaultEncoding
  228.  */
  229. protected String determineEncoding(HttpServletRequest request) {
  230. String enc = request.getCharacterEncoding();
  231. if (enc == null) {
  232. enc = this.defaultEncoding;
  233. }
  234. return enc;
  235. }
  236. public void cleanupMultipart(MultipartHttpServletRequest request) {
  237. Map multipartFiles = request.getFileMap();
  238. for (Iterator i = multipartFiles.keySet().iterator(); i.hasNext();) {
  239. String name = (String) i.next();
  240. CommonsMultipartFile file = (CommonsMultipartFile) multipartFiles.get(name);
  241. logger.debug("Cleaning up multipart file [" + file.getName() + "] with original file name [" +
  242.              file.getOriginalFilename() + "], stored " + file.getStorageDescription());
  243. file.getFileItem().delete();
  244. }
  245. }
  246. }