diff options
author | Emmanuel Bourg <ebourg@apache.org> | 2016-08-03 19:55:01 +0200 |
---|---|---|
committer | Emmanuel Bourg <ebourg@apache.org> | 2016-08-03 19:55:01 +0200 |
commit | 75a721d1019da2a2fa86e24ff439df4a224e5b19 (patch) | |
tree | 2c44c00ce2c8641cccad177177e5682e187a17ea /spring-web/src/main/java/org/springframework/web/multipart | |
parent | 9eaca6a06af3cbceb3754de19d477be770614265 (diff) |
Imported Upstream version 4.3.2
Diffstat (limited to 'spring-web/src/main/java/org/springframework/web/multipart')
4 files changed, 209 insertions, 28 deletions
diff --git a/spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsFileUploadSupport.java b/spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsFileUploadSupport.java index 622b1844..727bc92c 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsFileUploadSupport.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsFileUploadSupport.java @@ -304,7 +304,7 @@ public abstract class CommonsFileUploadSupport { return defaultEncoding; } MediaType contentType = MediaType.parseMediaType(contentTypeHeader); - Charset charset = contentType.getCharSet(); + Charset charset = contentType.getCharset(); return (charset != null ? charset.name() : defaultEncoding); } diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/MultipartFilter.java b/spring-web/src/main/java/org/springframework/web/multipart/support/MultipartFilter.java index b9ac26ed..577b4e3b 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/support/MultipartFilter.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/support/MultipartFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-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. @@ -39,6 +39,10 @@ import org.springframework.web.multipart.MultipartResolver; * <p>If no MultipartResolver bean is found, this filter falls back to a default * MultipartResolver: {@link StandardServletMultipartResolver} for Servlet 3.0, * based on a multipart-config section in {@code web.xml}. + * Note however that at present the Servlet specification only defines how to + * enable multipart configuration on a Servlet and as a result multipart request + * processing is likely not possible in a Filter unless the Servlet container + * provides a workaround such as Tomcat's "allowCasualMultipartParsing" property. * * <p>MultipartResolver lookup is customizable: Override this filter's * {@code lookupMultipartResolver} method to use a custom MultipartResolver diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/MultipartResolutionDelegate.java b/spring-web/src/main/java/org/springframework/web/multipart/support/MultipartResolutionDelegate.java new file mode 100644 index 00000000..42248276 --- /dev/null +++ b/spring-web/src/main/java/org/springframework/web/multipart/support/MultipartResolutionDelegate.java @@ -0,0 +1,199 @@ +/* + * Copyright 2002-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 org.springframework.web.multipart.support; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.Part; + +import org.springframework.core.GenericCollectionTypeResolver; +import org.springframework.core.MethodParameter; +import org.springframework.util.ClassUtils; +import org.springframework.web.multipart.MultipartException; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.web.util.WebUtils; + +/** + * A common delegate for {@code HandlerMethodArgumentResolver} implementations + * which need to resolve {@link MultipartFile} and {@link Part} arguments. + * + * @author Juergen Hoeller + * @since 4.3 + */ +public abstract class MultipartResolutionDelegate { + + public static final Object UNRESOLVABLE = new Object(); + + + private static Class<?> servletPartClass = null; + + static { + try { + servletPartClass = ClassUtils.forName("javax.servlet.http.Part", + MultipartResolutionDelegate.class.getClassLoader()); + } + catch (ClassNotFoundException ex) { + // Servlet 3.0 javax.servlet.http.Part type not available - + // Part references simply not supported then. + } + } + + + public static boolean isMultipartRequest(HttpServletRequest request) { + return (WebUtils.getNativeRequest(request, MultipartHttpServletRequest.class) != null || + isMultipartContent(request)); + } + + private static boolean isMultipartContent(HttpServletRequest request) { + String contentType = request.getContentType(); + return (contentType != null && contentType.toLowerCase().startsWith("multipart/")); + } + + static MultipartHttpServletRequest asMultipartHttpServletRequest(HttpServletRequest request) { + MultipartHttpServletRequest unwrapped = WebUtils.getNativeRequest(request, MultipartHttpServletRequest.class); + if (unwrapped != null) { + return unwrapped; + } + return adaptToMultipartHttpServletRequest(request); + } + + private static MultipartHttpServletRequest adaptToMultipartHttpServletRequest(HttpServletRequest request) { + if (servletPartClass != null) { + // Servlet 3.0 available .. + return new StandardMultipartHttpServletRequest(request); + } + throw new MultipartException("Expected MultipartHttpServletRequest: is a MultipartResolver configured?"); + } + + + public static boolean isMultipartArgument(MethodParameter parameter) { + Class<?> paramType = parameter.getNestedParameterType(); + return (MultipartFile.class == paramType || + isMultipartFileCollection(parameter) || isMultipartFileArray(parameter) || + (servletPartClass != null && (servletPartClass == paramType || + isPartCollection(parameter) || isPartArray(parameter)))); + } + + public static Object resolveMultipartArgument(String name, MethodParameter parameter, HttpServletRequest request) + throws Exception { + + MultipartHttpServletRequest multipartRequest = + WebUtils.getNativeRequest(request, MultipartHttpServletRequest.class); + boolean isMultipart = (multipartRequest != null || isMultipartContent(request)); + + if (MultipartFile.class == parameter.getNestedParameterType()) { + if (multipartRequest == null && isMultipart) { + multipartRequest = adaptToMultipartHttpServletRequest(request); + } + return (multipartRequest != null ? multipartRequest.getFile(name) : null); + } + else if (isMultipartFileCollection(parameter)) { + if (multipartRequest == null && isMultipart) { + multipartRequest = adaptToMultipartHttpServletRequest(request); + } + return (multipartRequest != null ? multipartRequest.getFiles(name) : null); + } + else if (isMultipartFileArray(parameter)) { + if (multipartRequest == null && isMultipart) { + multipartRequest = adaptToMultipartHttpServletRequest(request); + } + if (multipartRequest != null) { + List<MultipartFile> multipartFiles = multipartRequest.getFiles(name); + return multipartFiles.toArray(new MultipartFile[multipartFiles.size()]); + } + else { + return null; + } + } + else if (servletPartClass != null) { + if (servletPartClass == parameter.getNestedParameterType()) { + return (isMultipart ? RequestPartResolver.resolvePart(request, name) : null); + } + else if (isPartCollection(parameter)) { + return (isMultipart ? RequestPartResolver.resolvePartList(request, name) : null); + } + else if (isPartArray(parameter)) { + return (isMultipart ? RequestPartResolver.resolvePartArray(request, name) : null); + } + } + return UNRESOLVABLE; + } + + private static boolean isMultipartFileCollection(MethodParameter methodParam) { + return (MultipartFile.class == getCollectionParameterType(methodParam)); + } + + private static boolean isMultipartFileArray(MethodParameter methodParam) { + return (MultipartFile.class == methodParam.getNestedParameterType().getComponentType()); + } + + private static boolean isPartCollection(MethodParameter methodParam) { + return (servletPartClass == getCollectionParameterType(methodParam)); + } + + private static boolean isPartArray(MethodParameter methodParam) { + return (servletPartClass == methodParam.getNestedParameterType().getComponentType()); + } + + private static Class<?> getCollectionParameterType(MethodParameter methodParam) { + Class<?> paramType = methodParam.getNestedParameterType(); + if (Collection.class == paramType || List.class.isAssignableFrom(paramType)){ + Class<?> valueType = GenericCollectionTypeResolver.getCollectionParameterType(methodParam); + if (valueType != null) { + return valueType; + } + } + return null; + } + + + /** + * Inner class to avoid hard-coded dependency on Servlet 3.0 Part type... + */ + private static class RequestPartResolver { + + public static Object resolvePart(HttpServletRequest servletRequest, String name) throws Exception { + return servletRequest.getPart(name); + } + + public static Object resolvePartList(HttpServletRequest servletRequest, String name) throws Exception { + Collection<Part> parts = servletRequest.getParts(); + List<Part> result = new ArrayList<Part>(parts.size()); + for (Part part : parts) { + if (part.getName().equals(name)) { + result.add(part); + } + } + return result; + } + + public static Object resolvePartArray(HttpServletRequest servletRequest, String name) throws Exception { + Collection<Part> parts = servletRequest.getParts(); + List<Part> result = new ArrayList<Part>(parts.size()); + for (Part part : parts) { + if (part.getName().equals(name)) { + result.add(part); + } + } + return result.toArray(new Part[result.size()]); + } + } + +} diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/RequestPartServletServerHttpRequest.java b/spring-web/src/main/java/org/springframework/web/multipart/support/RequestPartServletServerHttpRequest.java index 78eab918..ae817e4b 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/support/RequestPartServletServerHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/support/RequestPartServletServerHttpRequest.java @@ -26,12 +26,10 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServletServerHttpRequest; -import org.springframework.util.ClassUtils; import org.springframework.web.multipart.MultipartException; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; import org.springframework.web.multipart.MultipartResolver; -import org.springframework.web.util.WebUtils; /** * {@link ServerHttpRequest} implementation that accesses one part of a multipart @@ -57,40 +55,20 @@ public class RequestPartServletServerHttpRequest extends ServletServerHttpReques * @param request the current servlet request * @param partName the name of the part to adapt to the {@link ServerHttpRequest} contract * @throws MissingServletRequestPartException if the request part cannot be found - * @throws IllegalArgumentException if MultipartHttpServletRequest cannot be initialized + * @throws MultipartException if MultipartHttpServletRequest cannot be initialized */ public RequestPartServletServerHttpRequest(HttpServletRequest request, String partName) throws MissingServletRequestPartException { super(request); - this.multipartRequest = asMultipartRequest(request); + this.multipartRequest = MultipartResolutionDelegate.asMultipartHttpServletRequest(request); this.partName = partName; this.headers = this.multipartRequest.getMultipartHeaders(this.partName); if (this.headers == null) { - if (request instanceof MultipartHttpServletRequest) { - throw new MissingServletRequestPartException(partName); - } - else { - throw new IllegalArgumentException( - "Failed to obtain request part: " + partName + ". " + - "The part is missing or multipart processing is not configured. " + - "Check for a MultipartResolver bean or if Servlet 3.0 multipart processing is enabled."); - } - } - } - - private static MultipartHttpServletRequest asMultipartRequest(HttpServletRequest request) { - MultipartHttpServletRequest unwrapped = WebUtils.getNativeRequest(request, MultipartHttpServletRequest.class); - if (unwrapped != null) { - return unwrapped; - } - else if (ClassUtils.hasMethod(HttpServletRequest.class, "getParts")) { - // Servlet 3.0 available .. - return new StandardMultipartHttpServletRequest(request); + throw new MissingServletRequestPartException(partName); } - throw new IllegalArgumentException("Expected MultipartHttpServletRequest: is a MultipartResolver configured?"); } @@ -125,7 +103,7 @@ public class RequestPartServletServerHttpRequest extends ServletServerHttpReques private String determineEncoding() { MediaType contentType = getHeaders().getContentType(); if (contentType != null) { - Charset charset = contentType.getCharSet(); + Charset charset = contentType.getCharset(); if (charset != null) { return charset.name(); } |