16
16
17
17
package org .springframework .web .method .annotation ;
18
18
19
+ import java .util .Collection ;
19
20
import java .util .LinkedHashMap ;
20
21
import java .util .Map ;
22
+ import javax .servlet .http .HttpServletRequest ;
23
+ import javax .servlet .http .Part ;
21
24
22
25
import org .springframework .core .MethodParameter ;
26
+ import org .springframework .core .ResolvableType ;
23
27
import org .springframework .lang .Nullable ;
24
28
import org .springframework .util .LinkedMultiValueMap ;
25
29
import org .springframework .util .MultiValueMap ;
29
33
import org .springframework .web .context .request .NativeWebRequest ;
30
34
import org .springframework .web .method .support .HandlerMethodArgumentResolver ;
31
35
import org .springframework .web .method .support .ModelAndViewContainer ;
36
+ import org .springframework .web .multipart .MultipartFile ;
37
+ import org .springframework .web .multipart .MultipartRequest ;
38
+ import org .springframework .web .multipart .support .MultipartResolutionDelegate ;
32
39
33
40
/**
34
41
* Resolves {@link Map} method arguments annotated with an @{@link RequestParam}
35
42
* where the annotation does not specify a request parameter name.
36
- * See {@link RequestParamMethodArgumentResolver} for resolving {@link Map}
37
- * method arguments with a request parameter name.
38
43
*
39
- * <p>The created {@link Map} contains all request parameter name/value pairs.
40
- * If the method parameter type is {@link MultiValueMap} instead, the created
41
- * map contains all request parameters and all there values for cases where
42
- * request parameters have multiple values.
44
+ * <p>The created {@link Map} contains all request parameter name/value pairs,
45
+ * or all multipart files for a given parameter name if specifically declared
46
+ * with {@link MultipartFile} as the value type. If the method parameter type is
47
+ * {@link MultiValueMap} instead, the created map contains all request parameters
48
+ * and all their values for cases where request parameters have multiple values
49
+ * (or multiple multipart files of the same name).
43
50
*
44
51
* @author Arjen Poutsma
45
52
* @author Rossen Stoyanchev
53
+ * @author Juergen Hoeller
46
54
* @since 3.1
47
55
* @see RequestParamMethodArgumentResolver
56
+ * @see HttpServletRequest#getParameterMap()
57
+ * @see MultipartRequest#getMultiFileMap()
58
+ * @see MultipartRequest#getFileMap()
48
59
*/
49
60
public class RequestParamMapMethodArgumentResolver implements HandlerMethodArgumentResolver {
50
61
@@ -59,26 +70,71 @@ public boolean supportsParameter(MethodParameter parameter) {
59
70
public Object resolveArgument (MethodParameter parameter , @ Nullable ModelAndViewContainer mavContainer ,
60
71
NativeWebRequest webRequest , @ Nullable WebDataBinderFactory binderFactory ) throws Exception {
61
72
62
- Class <?> paramType = parameter . getParameterType ( );
73
+ ResolvableType resolvableType = ResolvableType . forMethodParameter ( parameter );
63
74
64
- Map <String , String []> parameterMap = webRequest .getParameterMap ();
65
- if (MultiValueMap .class .isAssignableFrom (paramType )) {
66
- MultiValueMap <String , String > result = new LinkedMultiValueMap <>(parameterMap .size ());
67
- parameterMap .forEach ((key , values ) -> {
68
- for (String value : values ) {
69
- result .add (key , value );
75
+ if (MultiValueMap .class .isAssignableFrom (parameter .getParameterType ())) {
76
+ // MultiValueMap
77
+ Class <?> valueType = resolvableType .as (MultiValueMap .class ).getGeneric (1 ).resolve ();
78
+ if (valueType == MultipartFile .class ) {
79
+ MultipartRequest multipartRequest = MultipartResolutionDelegate .resolveMultipartRequest (webRequest );
80
+ return (multipartRequest != null ? multipartRequest .getMultiFileMap () : new LinkedMultiValueMap <>(0 ));
81
+ }
82
+ else if (valueType == Part .class ) {
83
+ HttpServletRequest servletRequest = webRequest .getNativeRequest (HttpServletRequest .class );
84
+ if (servletRequest != null && MultipartResolutionDelegate .isMultipartRequest (servletRequest )) {
85
+ Collection <Part > parts = servletRequest .getParts ();
86
+ LinkedMultiValueMap <String , Part > result = new LinkedMultiValueMap <>(parts .size ());
87
+ for (Part part : parts ) {
88
+ result .add (part .getName (), part );
89
+ }
90
+ return result ;
70
91
}
71
- });
72
- return result ;
92
+ return new LinkedMultiValueMap <>(0 );
93
+ }
94
+ else {
95
+ Map <String , String []> parameterMap = webRequest .getParameterMap ();
96
+ MultiValueMap <String , String > result = new LinkedMultiValueMap <>(parameterMap .size ());
97
+ parameterMap .forEach ((key , values ) -> {
98
+ for (String value : values ) {
99
+ result .add (key , value );
100
+ }
101
+ });
102
+ return result ;
103
+ }
73
104
}
105
+
74
106
else {
75
- Map <String , String > result = new LinkedHashMap <>(parameterMap .size ());
76
- parameterMap .forEach ((key , values ) -> {
77
- if (values .length > 0 ) {
78
- result .put (key , values [0 ]);
107
+ // Regular Map
108
+ Class <?> valueType = resolvableType .asMap ().getGeneric (1 ).resolve ();
109
+ if (valueType == MultipartFile .class ) {
110
+ MultipartRequest multipartRequest = MultipartResolutionDelegate .resolveMultipartRequest (webRequest );
111
+ return (multipartRequest != null ? multipartRequest .getFileMap () : new LinkedHashMap <>(0 ));
112
+ }
113
+ else if (valueType == Part .class ) {
114
+ HttpServletRequest servletRequest = webRequest .getNativeRequest (HttpServletRequest .class );
115
+ if (servletRequest != null && MultipartResolutionDelegate .isMultipartRequest (servletRequest )) {
116
+ Collection <Part > parts = servletRequest .getParts ();
117
+ LinkedHashMap <String , Part > result = new LinkedHashMap <>(parts .size ());
118
+ for (Part part : parts ) {
119
+ if (!result .containsKey (part .getName ())) {
120
+ result .put (part .getName (), part );
121
+ }
122
+ }
123
+ return result ;
79
124
}
80
- });
81
- return result ;
125
+ return new LinkedHashMap <>(0 );
126
+ }
127
+ else {
128
+ Map <String , String []> parameterMap = webRequest .getParameterMap ();
129
+ Map <String , String > result = new LinkedHashMap <>(parameterMap .size ());
130
+ parameterMap .forEach ((key , values ) -> {
131
+ if (values .length > 0 ) {
132
+ result .put (key , values [0 ]);
133
+ }
134
+ });
135
+ return result ;
136
+ }
82
137
}
83
138
}
139
+
84
140
}
0 commit comments