/** * {@link EnableAutoConfiguration Auto-configuration} for multi-part uploads. Adds a * {@link StandardServletMultipartResolver} if none is present, and adds a * {@link javax.servlet.MultipartConfigElement multipartConfigElement} if none is * otherwise defined. The {@link ServletWebServerApplicationContext} will associate the * {@link MultipartConfigElement} bean to any {@link Servlet} beans. * <p> * The {@link javax.servlet.MultipartConfigElement} is a Servlet API that's used to * configure how the server handles file uploads. * * @author Greg Turnquist * @author Josh Long * @author Toshiaki Maki * @since 2.0.0 */ @Configuration(proxyBeanMethods = false) @ConditionalOnClass({ Servlet.class, StandardServletMultipartResolver.class, MultipartConfigElement.class }) @ConditionalOnProperty(prefix = "spring.servlet.multipart", name = "enabled", matchIfMissing = true) @ConditionalOnWebApplication(type = Type.SERVLET) @EnableConfigurationProperties(MultipartProperties.class) publicclassMultipartAutoConfiguration{
/** * Servlet-based {@link MultipartResolver} implementation for * <a href="https://commons.apache.org/proper/commons-fileupload">Apache Commons FileUpload</a> * 1.2 or above. * * <p>Provides "maxUploadSize", "maxInMemorySize" and "defaultEncoding" settings as * bean properties (inherited from {@link CommonsFileUploadSupport}). See corresponding * ServletFileUpload / DiskFileItemFactory properties ("sizeMax", "sizeThreshold", * "headerEncoding") for details in terms of defaults and accepted values. * * <p>Saves temporary files to the servlet container's temporary directory. * Needs to be initialized <i>either</i> by an application context <i>or</i> * via the constructor that takes a ServletContext (for standalone usage). * * @author Trevor D. Cook * @author Juergen Hoeller * @since 29.09.2003 * @see #CommonsMultipartResolver(ServletContext) * @see #setResolveLazily * @see org.apache.commons.fileupload.servlet.ServletFileUpload * @see org.apache.commons.fileupload.disk.DiskFileItemFactory */ publicclassCommonsMultipartResolverextendsCommonsFileUploadSupport implementsMultipartResolver, ServletContextAware{
privateboolean resolveLazily = false;
/** * Constructor for use as bean. Determines the servlet container's * temporary directory via the ServletContext passed in as through the * ServletContextAware interface (typically by a WebApplicationContext). * @see #setServletContext * @see org.springframework.web.context.ServletContextAware * @see org.springframework.web.context.WebApplicationContext */ publicCommonsMultipartResolver(){ super(); }
/** * Constructor for standalone usage. Determines the servlet container's * temporary directory via the given ServletContext. * @param servletContext the ServletContext to use */ publicCommonsMultipartResolver(ServletContext servletContext){ this(); setServletContext(servletContext); }
/** * Set whether to resolve the multipart request lazily at the time of * file or parameter access. * <p>Default is "false", resolving the multipart elements immediately, throwing * corresponding exceptions at the time of the {@link #resolveMultipart} call. * Switch this to "true" for lazy multipart parsing, throwing parse exceptions * once the application attempts to obtain multipart files or parameters. */ publicvoidsetResolveLazily(boolean resolveLazily){ this.resolveLazily = resolveLazily; }
/** * Initialize the underlying {@code org.apache.commons.fileupload.servlet.ServletFileUpload} * instance. Can be overridden to use a custom subclass, e.g. for testing purposes. * @param fileItemFactory the Commons FileItemFactory to use * @return the new ServletFileUpload instance */ @Override protected FileUpload newFileUpload(FileItemFactory fileItemFactory){ returnnew ServletFileUpload(fileItemFactory); }
@Override publicvoidsetServletContext(ServletContext servletContext){ if (!isUploadTempDirSpecified()) { getFileItemFactory().setRepository(WebUtils.getTempDir(servletContext)); } }
@Override public MultipartHttpServletRequest resolveMultipart(final HttpServletRequest request)throws MultipartException { Assert.notNull(request, "Request must not be null"); if (this.resolveLazily) { returnnew DefaultMultipartHttpServletRequest(request) { @Override protectedvoidinitializeMultipart(){ MultipartParsingResult parsingResult = parseRequest(request); setMultipartFiles(parsingResult.getMultipartFiles()); setMultipartParameters(parsingResult.getMultipartParameters()); setMultipartParameterContentTypes(parsingResult.getMultipartParameterContentTypes()); } }; } else { MultipartParsingResult parsingResult = parseRequest(request); returnnew DefaultMultipartHttpServletRequest(request, parsingResult.getMultipartFiles(), parsingResult.getMultipartParameters(), parsingResult.getMultipartParameterContentTypes()); } }
/** * Parse the given servlet request, resolving its multipart elements. * @param request the request to parse * @return the parsing result * @throws MultipartException if multipart resolution failed. */ protected MultipartParsingResult parseRequest(HttpServletRequest request)throws MultipartException { String encoding = determineEncoding(request); FileUpload fileUpload = prepareFileUpload(encoding); try { List<FileItem> fileItems = ((ServletFileUpload) fileUpload).parseRequest(request); return parseFileItems(fileItems, encoding); } catch (FileUploadBase.SizeLimitExceededException ex) { thrownew MaxUploadSizeExceededException(fileUpload.getSizeMax(), ex); } catch (FileUploadBase.FileSizeLimitExceededException ex) { thrownew MaxUploadSizeExceededException(fileUpload.getFileSizeMax(), ex); } catch (FileUploadException ex) { thrownew MultipartException("Failed to parse multipart servlet request", ex); } }
/** * Determine the encoding for the given request. * Can be overridden in subclasses. * <p>The default implementation checks the request encoding, * falling back to the default encoding specified for this resolver. * @param request current HTTP request * @return the encoding for the request (never {@code null}) * @see javax.servlet.ServletRequest#getCharacterEncoding * @see #setDefaultEncoding */ protected String determineEncoding(HttpServletRequest request){ String encoding = request.getCharacterEncoding(); if (encoding == null) { encoding = getDefaultEncoding(); } return encoding; }