1919import java .lang .reflect .AnnotatedElement ;
2020import java .lang .reflect .Method ;
2121import java .lang .reflect .Parameter ;
22+ import java .lang .reflect .Type ;
2223
2324import org .springframework .aot .hint .ExecutableMode ;
2425import org .springframework .aot .hint .ReflectionHints ;
2526import org .springframework .aot .hint .annotation .ReflectiveProcessor ;
2627import org .springframework .aot .hint .support .BindingReflectionHintsRegistrar ;
2728import org .springframework .core .MethodParameter ;
2829import org .springframework .core .annotation .AnnotatedElementUtils ;
30+ import org .springframework .http .HttpEntity ;
31+ import org .springframework .lang .Nullable ;
2932
3033/**
3134 * {@link ReflectiveProcessor} implementation for {@link RequestMapping}
3235 * 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>
3642 *
3743 * @author Stephane Nicoll
3844 * @author Sebastien Deleuze
@@ -45,29 +51,51 @@ class RequestMappingReflectiveProcessor implements ReflectiveProcessor {
4551 @ Override
4652 public void registerReflectionHints (ReflectionHints hints , AnnotatedElement element ) {
4753 if (element instanceof Class <?> type ) {
48- registerTypeHint (hints , type );
54+ registerTypeHints (hints , type );
4955 }
5056 else if (element instanceof Method method ) {
51- registerMethodHint (hints , method );
57+ registerMethodHints (hints , method );
5258 }
5359 }
5460
55- protected void registerTypeHint (ReflectionHints hints , Class <?> type ) {
61+ protected void registerTypeHints (ReflectionHints hints , Class <?> type ) {
5662 hints .registerType (type , hint -> {});
5763 }
5864
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 ) {
6072 hints .registerMethod (method , hint -> hint .setModes (ExecutableMode .INVOKE ));
6173 for (Parameter parameter : method .getParameters ()) {
6274 MethodParameter methodParameter = MethodParameter .forParameter (parameter );
6375 if (methodParameter .hasParameterAnnotation (RequestBody .class )) {
6476 this .bindingRegistrar .registerReflectionHints (hints , methodParameter .getGenericParameterType ());
6577 }
78+ else if (HttpEntity .class .isAssignableFrom (methodParameter .getParameterType ())) {
79+ this .bindingRegistrar .registerReflectionHints (hints , getHttpEntityType (methodParameter ));
80+ }
6681 }
82+ }
83+
84+ protected void registerReturnValueHints (ReflectionHints hints , Method method ) {
6785 MethodParameter returnType = MethodParameter .forExecutable (method , -1 );
6886 if (AnnotatedElementUtils .hasAnnotation (returnType .getContainingClass (), ResponseBody .class ) ||
6987 returnType .hasMethodAnnotation (ResponseBody .class )) {
7088 this .bindingRegistrar .registerReflectionHints (hints , returnType .getGenericParameterType ());
7189 }
90+ else if (HttpEntity .class .isAssignableFrom (returnType .getParameterType ())) {
91+ this .bindingRegistrar .registerReflectionHints (hints , getHttpEntityType (returnType ));
92+ }
7293 }
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+
73101}
0 commit comments