summaryrefslogtreecommitdiff
path: root/spring-web/src/main/java/org/springframework/web/multipart
diff options
context:
space:
mode:
authorEmmanuel Bourg <ebourg@apache.org>2016-08-03 19:55:01 +0200
committerEmmanuel Bourg <ebourg@apache.org>2016-08-03 19:55:01 +0200
commit75a721d1019da2a2fa86e24ff439df4a224e5b19 (patch)
tree2c44c00ce2c8641cccad177177e5682e187a17ea /spring-web/src/main/java/org/springframework/web/multipart
parent9eaca6a06af3cbceb3754de19d477be770614265 (diff)
Imported Upstream version 4.3.2
Diffstat (limited to 'spring-web/src/main/java/org/springframework/web/multipart')
-rw-r--r--spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsFileUploadSupport.java2
-rw-r--r--spring-web/src/main/java/org/springframework/web/multipart/support/MultipartFilter.java6
-rw-r--r--spring-web/src/main/java/org/springframework/web/multipart/support/MultipartResolutionDelegate.java199
-rw-r--r--spring-web/src/main/java/org/springframework/web/multipart/support/RequestPartServletServerHttpRequest.java30
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();
}