Skip to content

Commit 3c709a7

Browse files
committed
Servlet 3 multipart request implements getParameterNames defensively (for WebLogic 12 compatibility)
This commit also includes lazy resolution support for StandardServletMultipartResolver, along the lines of existing lazy mode in CommonsMultipartResolver. Issue: SPR-11074 Issue: SPR-11730 (cherry picked from commit 82336c3)
1 parent 7d78c65 commit 3c709a7

File tree

3 files changed

+83
-8
lines changed

3 files changed

+83
-8
lines changed

spring-web/src/main/java/org/springframework/web/multipart/support/DefaultMultipartHttpServletRequest.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,7 +19,7 @@
1919
import java.util.Collections;
2020
import java.util.Enumeration;
2121
import java.util.HashMap;
22-
import java.util.HashSet;
22+
import java.util.LinkedHashSet;
2323
import java.util.Map;
2424
import java.util.Set;
2525
import javax.servlet.http.HttpServletRequest;
@@ -33,6 +33,8 @@
3333
* {@link org.springframework.web.multipart.MultipartHttpServletRequest}
3434
* interface. Provides management of pre-generated parameter values.
3535
*
36+
* <p>Used by {@link org.springframework.web.multipart.commons.CommonsMultipartResolver}.
37+
*
3638
* @author Trevor D. Cook
3739
* @author Juergen Hoeller
3840
* @author Arjen Poutsma
@@ -75,12 +77,17 @@ public DefaultMultipartHttpServletRequest(HttpServletRequest request) {
7577

7678
@Override
7779
public Enumeration<String> getParameterNames() {
78-
Set<String> paramNames = new HashSet<String>();
80+
Map<String, String[]> multipartParameters = getMultipartParameters();
81+
if (multipartParameters.isEmpty()) {
82+
return super.getParameterNames();
83+
}
84+
85+
Set<String> paramNames = new LinkedHashSet<String>();
7986
Enumeration<String> paramEnum = super.getParameterNames();
8087
while (paramEnum.hasMoreElements()) {
8188
paramNames.add(paramEnum.nextElement());
8289
}
83-
paramNames.addAll(getMultipartParameters().keySet());
90+
paramNames.addAll(multipartParameters.keySet());
8491
return Collections.enumeration(paramNames);
8592
}
8693

spring-web/src/main/java/org/springframework/web/multipart/support/StandardMultipartHttpServletRequest.java

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -21,6 +21,10 @@
2121
import java.io.InputStream;
2222
import java.util.ArrayList;
2323
import java.util.Collection;
24+
import java.util.Collections;
25+
import java.util.Enumeration;
26+
import java.util.LinkedHashSet;
27+
import java.util.Set;
2428
import javax.servlet.http.HttpServletRequest;
2529
import javax.servlet.http.Part;
2630

@@ -45,22 +49,47 @@ public class StandardMultipartHttpServletRequest extends AbstractMultipartHttpSe
4549

4650
private static final String FILENAME_KEY = "filename=";
4751

52+
private Set<String> multipartParameterNames;
53+
4854

4955
/**
50-
* Create a new StandardMultipartHttpServletRequest wrapper for the given request.
56+
* Create a new StandardMultipartHttpServletRequest wrapper for the given request,
57+
* immediately parsing the multipart content.
5158
* @param request the servlet request to wrap
5259
* @throws MultipartException if parsing failed
5360
*/
5461
public StandardMultipartHttpServletRequest(HttpServletRequest request) throws MultipartException {
62+
this(request, false);
63+
}
64+
65+
/**
66+
* Create a new StandardMultipartHttpServletRequest wrapper for the given request.
67+
* @param request the servlet request to wrap
68+
* @param lazyParsing whether multipart parsing should be triggered lazily on
69+
* first access of multipart files or parameters
70+
* @throws MultipartException if an immediate parsing attempt failed
71+
*/
72+
public StandardMultipartHttpServletRequest(HttpServletRequest request, boolean lazyParsing) throws MultipartException {
5573
super(request);
74+
if (!lazyParsing) {
75+
parseRequest(request);
76+
}
77+
}
78+
79+
80+
private void parseRequest(HttpServletRequest request) {
5681
try {
5782
Collection<Part> parts = request.getParts();
83+
this.multipartParameterNames = new LinkedHashSet<String>(parts.size());
5884
MultiValueMap<String, MultipartFile> files = new LinkedMultiValueMap<String, MultipartFile>(parts.size());
5985
for (Part part : parts) {
6086
String filename = extractFilename(part.getHeader(CONTENT_DISPOSITION));
6187
if (filename != null) {
6288
files.add(part.getName(), new StandardMultipartFile(part, filename));
6389
}
90+
else {
91+
this.multipartParameterNames.add(part.getName());
92+
}
6493
}
6594
setMultipartFiles(files);
6695
}
@@ -95,6 +124,29 @@ private String extractFilename(String contentDisposition) {
95124
}
96125

97126

127+
@Override
128+
protected void initializeMultipart() {
129+
parseRequest(getRequest());
130+
}
131+
132+
@Override
133+
public Enumeration<String> getParameterNames() {
134+
if (this.multipartParameterNames == null) {
135+
initializeMultipart();
136+
}
137+
if (this.multipartParameterNames.isEmpty()) {
138+
return super.getParameterNames();
139+
}
140+
141+
Set<String> paramNames = new LinkedHashSet<String>();
142+
Enumeration<String> paramEnum = super.getParameterNames();
143+
while (paramEnum.hasMoreElements()) {
144+
paramNames.add(paramEnum.nextElement());
145+
}
146+
paramNames.addAll(this.multipartParameterNames);
147+
return Collections.enumeration(paramNames);
148+
}
149+
98150
@Override
99151
public String getMultipartContentType(String paramOrFileName) {
100152
try {

spring-web/src/main/java/org/springframework/web/multipart/support/StandardServletMultipartResolver.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -45,6 +45,22 @@
4545
*/
4646
public class StandardServletMultipartResolver implements MultipartResolver {
4747

48+
private boolean resolveLazily = false;
49+
50+
51+
/**
52+
* Set whether to resolve the multipart request lazily at the time of
53+
* file or parameter access.
54+
* <p>Default is "false", resolving the multipart elements immediately, throwing
55+
* corresponding exceptions at the time of the {@link #resolveMultipart} call.
56+
* Switch this to "true" for lazy multipart parsing, throwing parse exceptions
57+
* once the application attempts to obtain multipart files or parameters.
58+
*/
59+
public void setResolveLazily(boolean resolveLazily) {
60+
this.resolveLazily = resolveLazily;
61+
}
62+
63+
4864
@Override
4965
public boolean isMultipart(HttpServletRequest request) {
5066
// Same check as in Commons FileUpload...
@@ -57,7 +73,7 @@ public boolean isMultipart(HttpServletRequest request) {
5773

5874
@Override
5975
public MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) throws MultipartException {
60-
return new StandardMultipartHttpServletRequest(request);
76+
return new StandardMultipartHttpServletRequest(request, this.resolveLazily);
6177
}
6278

6379
@Override

0 commit comments

Comments
 (0)