19
19
import java .lang .reflect .AnnotatedElement ;
20
20
import java .lang .reflect .Method ;
21
21
import java .lang .reflect .Parameter ;
22
+ import java .lang .reflect .Type ;
22
23
23
24
import org .springframework .aot .hint .ExecutableMode ;
24
25
import org .springframework .aot .hint .ReflectionHints ;
25
26
import org .springframework .aot .hint .annotation .ReflectiveProcessor ;
26
27
import org .springframework .aot .hint .support .BindingReflectionHintsRegistrar ;
27
28
import org .springframework .core .MethodParameter ;
28
29
import org .springframework .core .annotation .AnnotatedElementUtils ;
30
+ import org .springframework .http .HttpEntity ;
31
+ import org .springframework .lang .Nullable ;
29
32
30
33
/**
31
34
* {@link ReflectiveProcessor} implementation for {@link RequestMapping}
32
35
* annotated types. On top of registering reflection hints for invoking
33
- * the annotated method, this implementation handles return types annotated
34
- * with {@link ResponseBody} and parameters annotated with {@link RequestBody}
35
- * which are serialized as well.
36
+ * the annotated method, this implementation handles:
37
+ * <ul>
38
+ * <li>Return types annotated with {@link ResponseBody}.</li>
39
+ * <li>Parameters annotated with {@link RequestBody}.</li>
40
+ * <li>{@link HttpEntity} return type and parameters.</li>
41
+ * </ul>
36
42
*
37
43
* @author Stephane Nicoll
38
44
* @author Sebastien Deleuze
@@ -45,29 +51,51 @@ class RequestMappingReflectiveProcessor implements ReflectiveProcessor {
45
51
@ Override
46
52
public void registerReflectionHints (ReflectionHints hints , AnnotatedElement element ) {
47
53
if (element instanceof Class <?> type ) {
48
- registerTypeHint (hints , type );
54
+ registerTypeHints (hints , type );
49
55
}
50
56
else if (element instanceof Method method ) {
51
- registerMethodHint (hints , method );
57
+ registerMethodHints (hints , method );
52
58
}
53
59
}
54
60
55
- protected void registerTypeHint (ReflectionHints hints , Class <?> type ) {
61
+ protected void registerTypeHints (ReflectionHints hints , Class <?> type ) {
56
62
hints .registerType (type , hint -> {});
57
63
}
58
64
59
- protected void registerMethodHint (ReflectionHints hints , Method method ) {
65
+ protected void registerMethodHints (ReflectionHints hints , Method method ) {
66
+ hints .registerMethod (method , hint -> hint .setModes (ExecutableMode .INVOKE ));
67
+ registerParameterHints (hints , method );
68
+ registerReturnValueHints (hints , method );
69
+ }
70
+
71
+ protected void registerParameterHints (ReflectionHints hints , Method method ) {
60
72
hints .registerMethod (method , hint -> hint .setModes (ExecutableMode .INVOKE ));
61
73
for (Parameter parameter : method .getParameters ()) {
62
74
MethodParameter methodParameter = MethodParameter .forParameter (parameter );
63
75
if (methodParameter .hasParameterAnnotation (RequestBody .class )) {
64
76
this .bindingRegistrar .registerReflectionHints (hints , methodParameter .getGenericParameterType ());
65
77
}
78
+ else if (HttpEntity .class .isAssignableFrom (methodParameter .getParameterType ())) {
79
+ this .bindingRegistrar .registerReflectionHints (hints , getHttpEntityType (methodParameter ));
80
+ }
66
81
}
82
+ }
83
+
84
+ protected void registerReturnValueHints (ReflectionHints hints , Method method ) {
67
85
MethodParameter returnType = MethodParameter .forExecutable (method , -1 );
68
86
if (AnnotatedElementUtils .hasAnnotation (returnType .getContainingClass (), ResponseBody .class ) ||
69
87
returnType .hasMethodAnnotation (ResponseBody .class )) {
70
88
this .bindingRegistrar .registerReflectionHints (hints , returnType .getGenericParameterType ());
71
89
}
90
+ else if (HttpEntity .class .isAssignableFrom (returnType .getParameterType ())) {
91
+ this .bindingRegistrar .registerReflectionHints (hints , getHttpEntityType (returnType ));
92
+ }
72
93
}
94
+
95
+ @ Nullable
96
+ protected Type getHttpEntityType (MethodParameter parameter ) {
97
+ MethodParameter nestedParameter = parameter .nested ();
98
+ return (nestedParameter .getNestedParameterType () == nestedParameter .getParameterType () ? null : nestedParameter .getNestedParameterType ());
99
+ }
100
+
73
101
}
0 commit comments