diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/DefaultMultipartHttpServletRequest.java b/spring-web/src/main/java/org/springframework/web/multipart/support/DefaultMultipartHttpServletRequest.java
index 86a8f79c4a..b1cea0cbb4 100644
--- a/spring-web/src/main/java/org/springframework/web/multipart/support/DefaultMultipartHttpServletRequest.java
+++ b/spring-web/src/main/java/org/springframework/web/multipart/support/DefaultMultipartHttpServletRequest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2014 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.
@@ -19,7 +19,7 @@ package org.springframework.web.multipart.support;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
-import java.util.HashSet;
+import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
@@ -33,6 +33,8 @@ import org.springframework.web.multipart.MultipartFile;
* {@link org.springframework.web.multipart.MultipartHttpServletRequest}
* interface. Provides management of pre-generated parameter values.
*
+ *
Used by {@link org.springframework.web.multipart.commons.CommonsMultipartResolver}.
+ *
* @author Trevor D. Cook
* @author Juergen Hoeller
* @author Arjen Poutsma
@@ -75,12 +77,17 @@ public class DefaultMultipartHttpServletRequest extends AbstractMultipartHttpSer
@Override
public Enumeration getParameterNames() {
- Set paramNames = new HashSet();
+ Map multipartParameters = getMultipartParameters();
+ if (multipartParameters.isEmpty()) {
+ return super.getParameterNames();
+ }
+
+ Set paramNames = new LinkedHashSet();
Enumeration paramEnum = super.getParameterNames();
while (paramEnum.hasMoreElements()) {
paramNames.add(paramEnum.nextElement());
}
- paramNames.addAll(getMultipartParameters().keySet());
+ paramNames.addAll(multipartParameters.keySet());
return Collections.enumeration(paramNames);
}
diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/StandardMultipartHttpServletRequest.java b/spring-web/src/main/java/org/springframework/web/multipart/support/StandardMultipartHttpServletRequest.java
index 46a9886fe2..90cb3d6386 100644
--- a/spring-web/src/main/java/org/springframework/web/multipart/support/StandardMultipartHttpServletRequest.java
+++ b/spring-web/src/main/java/org/springframework/web/multipart/support/StandardMultipartHttpServletRequest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2014 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.
@@ -21,6 +21,10 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.LinkedHashSet;
+import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;
@@ -45,22 +49,47 @@ public class StandardMultipartHttpServletRequest extends AbstractMultipartHttpSe
private static final String FILENAME_KEY = "filename=";
+ private Set multipartParameterNames;
+
/**
- * Create a new StandardMultipartHttpServletRequest wrapper for the given request.
+ * Create a new StandardMultipartHttpServletRequest wrapper for the given request,
+ * immediately parsing the multipart content.
* @param request the servlet request to wrap
* @throws MultipartException if parsing failed
*/
public StandardMultipartHttpServletRequest(HttpServletRequest request) throws MultipartException {
+ this(request, false);
+ }
+
+ /**
+ * Create a new StandardMultipartHttpServletRequest wrapper for the given request.
+ * @param request the servlet request to wrap
+ * @param lazyParsing whether multipart parsing should be triggered lazily on
+ * first access of multipart files or parameters
+ * @throws MultipartException if an immediate parsing attempt failed
+ */
+ public StandardMultipartHttpServletRequest(HttpServletRequest request, boolean lazyParsing) throws MultipartException {
super(request);
+ if (!lazyParsing) {
+ parseRequest(request);
+ }
+ }
+
+
+ private void parseRequest(HttpServletRequest request) {
try {
Collection parts = request.getParts();
+ this.multipartParameterNames = new LinkedHashSet(parts.size());
MultiValueMap files = new LinkedMultiValueMap(parts.size());
for (Part part : parts) {
String filename = extractFilename(part.getHeader(CONTENT_DISPOSITION));
if (filename != null) {
files.add(part.getName(), new StandardMultipartFile(part, filename));
}
+ else {
+ this.multipartParameterNames.add(part.getName());
+ }
}
setMultipartFiles(files);
}
@@ -95,6 +124,29 @@ public class StandardMultipartHttpServletRequest extends AbstractMultipartHttpSe
}
+ @Override
+ protected void initializeMultipart() {
+ parseRequest(getRequest());
+ }
+
+ @Override
+ public Enumeration getParameterNames() {
+ if (this.multipartParameterNames == null) {
+ initializeMultipart();
+ }
+ if (this.multipartParameterNames.isEmpty()) {
+ return super.getParameterNames();
+ }
+
+ Set paramNames = new LinkedHashSet();
+ Enumeration paramEnum = super.getParameterNames();
+ while (paramEnum.hasMoreElements()) {
+ paramNames.add(paramEnum.nextElement());
+ }
+ paramNames.addAll(this.multipartParameterNames);
+ return Collections.enumeration(paramNames);
+ }
+
@Override
public String getMultipartContentType(String paramOrFileName) {
try {
diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/StandardServletMultipartResolver.java b/spring-web/src/main/java/org/springframework/web/multipart/support/StandardServletMultipartResolver.java
index 25cc39510a..91269a65c4 100644
--- a/spring-web/src/main/java/org/springframework/web/multipart/support/StandardServletMultipartResolver.java
+++ b/spring-web/src/main/java/org/springframework/web/multipart/support/StandardServletMultipartResolver.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2014 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.
@@ -45,6 +45,22 @@ import org.springframework.web.multipart.MultipartResolver;
*/
public class StandardServletMultipartResolver implements MultipartResolver {
+ private boolean resolveLazily = false;
+
+
+ /**
+ * Set whether to resolve the multipart request lazily at the time of
+ * file or parameter access.
+ * 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.
+ */
+ public void setResolveLazily(boolean resolveLazily) {
+ this.resolveLazily = resolveLazily;
+ }
+
+
@Override
public boolean isMultipart(HttpServletRequest request) {
// Same check as in Commons FileUpload...
@@ -57,7 +73,7 @@ public class StandardServletMultipartResolver implements MultipartResolver {
@Override
public MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) throws MultipartException {
- return new StandardMultipartHttpServletRequest(request);
+ return new StandardMultipartHttpServletRequest(request, this.resolveLazily);
}
@Override