Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 47abad4

Browse files
onobcmp911de
authored andcommitted
Avoid matching multipart parameters annotated with @ModelAttribute
The ProxyHandlerMethodArgumentResolver now avoids matching multipart parameters annotated with @ModelAttribute. This allows multipart parameters to be handled by RequestParamMethodArgumentResolver which properly handles multipart arguments. Also, the `@ProjectedPayload` annotation can now be used on parameters. This prepares for the upcoming removal of support for non-annotated projections. Fixes #3258 Related tickets #2937 Original pull request: #3277 Signed-off-by: Chris Bono <chris.bono@broadcom.com>
1 parent 6c4952c commit 47abad4

File tree

3 files changed

+42
-8
lines changed

3 files changed

+42
-8
lines changed

‎src/main/java/org/springframework/data/web/ProjectedPayload.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,23 @@
1515
*/
1616
package org.springframework.data.web;
1717

18-
import static java.lang.annotation.ElementType.*;
19-
import static java.lang.annotation.RetentionPolicy.*;
20-
2118
import java.lang.annotation.Documented;
19+
import java.lang.annotation.ElementType;
2220
import java.lang.annotation.Retention;
21+
import java.lang.annotation.RetentionPolicy;
2322
import java.lang.annotation.Target;
2423

2524
/**
2625
* Annotation to mark projection interfaces that are supposed to be used as projection interface to bind request or
2726
* response payloads to.
2827
*
2928
* @author Oliver Gierke
29+
* @author Chris Bono
3030
* @soundtrack
3131
* @since 1.13
3232
*/
3333
@Documented
34-
@Retention(RUNTIME)
35-
@Target(TYPE)
34+
@Retention(RetentionPolicy.RUNTIME)
35+
@Target({ ElementType.TYPE, ElementType.PARAMETER })
3636
public @interface ProjectedPayload {
3737
}

‎src/main/java/org/springframework/data/web/ProxyingHandlerMethodArgumentResolver.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,13 @@
3636
import org.springframework.web.context.request.NativeWebRequest;
3737
import org.springframework.web.method.annotation.ModelAttributeMethodProcessor;
3838
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
39+
import org.springframework.web.multipart.support.MultipartResolutionDelegate;
3940

4041
/**
4142
* {@link HandlerMethodArgumentResolver} to create Proxy instances for interface based controller method parameters.
4243
*
4344
* @author Oliver Gierke
45+
* @author Chris Bono
4446
* @since 1.10
4547
*/
4648
public class ProxyingHandlerMethodArgumentResolver extends ModelAttributeMethodProcessor
@@ -88,9 +90,9 @@ public boolean supportsParameter(MethodParameter parameter) {
8890
return false;
8991
}
9092

91-
// Annotated parameter
92-
if (parameter.getParameterAnnotation(ProjectedPayload.class) != null
93-
|| parameter.getParameterAnnotation(ModelAttribute.class) != null) {
93+
// Annotated parameter (excluding multipart)
94+
if ((parameter.hasParameterAnnotation(ProjectedPayload.class) || parameter.hasParameterAnnotation(
95+
ModelAttribute.class)) && !MultipartResolutionDelegate.isMultipartArgument(parameter)) {
9496
return true;
9597
}
9698

‎src/test/java/org/springframework/data/web/ProxyingHandlerMethodArgumentResolverUnitTests.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,13 @@
2727
import org.springframework.core.convert.support.DefaultConversionService;
2828
import org.springframework.util.ReflectionUtils;
2929
import org.springframework.web.bind.annotation.ModelAttribute;
30+
import org.springframework.web.multipart.MultipartFile;
3031

3132
/**
3233
* Unit tests for {@link ProxyingHandlerMethodArgumentResolver}.
3334
*
3435
* @author Oliver Gierke
36+
* @author Chris Bono
3537
* @soundtrack Karlijn Langendijk & Sönke Meinen - Englishman In New York (Sting,
3638
* https://www.youtube.com/watch?v=O7LZsqrnaaA)
3739
*/
@@ -88,6 +90,30 @@ void doesSupportAtModelAttribute() throws Exception {
8890
assertThat(resolver.supportsParameter(parameter)).isTrue();
8991
}
9092

93+
@Test // GH-3258
94+
void doesNotSupportAtModelAttributeForMultipartParam() throws Exception {
95+
96+
var parameter = getParameter("withModelAttributeMultipart", MultipartFile.class);
97+
98+
assertThat(resolver.supportsParameter(parameter)).isFalse();
99+
}
100+
101+
@Test // GH-3258
102+
void doesSupportAtProjectedPayload() throws Exception {
103+
104+
var parameter = getParameter("withProjectedPayload", SampleInterface.class);
105+
106+
assertThat(resolver.supportsParameter(parameter)).isTrue();
107+
}
108+
109+
@Test // GH-3258
110+
void doesNotSupportAtProjectedPayloadForMultipartParam() throws Exception {
111+
112+
var parameter = getParameter("withProjectedPayloadMultipart", MultipartFile.class);
113+
114+
assertThat(resolver.supportsParameter(parameter)).isFalse();
115+
}
116+
91117
private static MethodParameter getParameter(String methodName, Class<?> parameterType) {
92118

93119
var method = ReflectionUtils.findMethod(Controller.class, methodName, parameterType);
@@ -112,5 +138,11 @@ interface Controller {
112138
void withForeignAnnotation(@Autowired SampleInterface param);
113139

114140
void withModelAttribute(@ModelAttribute SampleInterface param);
141+
142+
void withModelAttributeMultipart(@ModelAttribute MultipartFile file);
143+
144+
void withProjectedPayload(@ProjectedPayload SampleInterface param);
145+
146+
void withProjectedPayloadMultipart(@ProjectedPayload MultipartFile file);
115147
}
116148
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /