From 9d42779826b84fc5e4060c3b14287c33eef72835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deleuze?= Date: Mon, 11 Jul 2022 11:37:41 +0200 Subject: [PATCH] Add reflection hints for data binding in Web controllers Closes gh-28623 --- .../RequestMappingReflectiveProcessor.java | 3 ++- ...equestMappingReflectiveProcessorTests.java | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/spring-web/src/main/java/org/springframework/web/bind/annotation/RequestMappingReflectiveProcessor.java b/spring-web/src/main/java/org/springframework/web/bind/annotation/RequestMappingReflectiveProcessor.java index a39ae5b0ba..c1661d39f6 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/annotation/RequestMappingReflectiveProcessor.java +++ b/spring-web/src/main/java/org/springframework/web/bind/annotation/RequestMappingReflectiveProcessor.java @@ -72,7 +72,8 @@ class RequestMappingReflectiveProcessor implements ReflectiveProcessor { hints.registerMethod(method, hint -> hint.setModes(ExecutableMode.INVOKE)); for (Parameter parameter : method.getParameters()) { MethodParameter methodParameter = MethodParameter.forParameter(parameter); - if (methodParameter.hasParameterAnnotation(RequestBody.class)) { + if (methodParameter.hasParameterAnnotation(RequestBody.class) || + methodParameter.hasParameterAnnotation(ModelAttribute.class)) { this.bindingRegistrar.registerReflectionHints(hints, methodParameter.getGenericParameterType()); } else if (HttpEntity.class.isAssignableFrom(methodParameter.getParameterType())) { diff --git a/spring-web/src/test/java/org/springframework/web/bind/annotation/RequestMappingReflectiveProcessorTests.java b/spring-web/src/test/java/org/springframework/web/bind/annotation/RequestMappingReflectiveProcessorTests.java index c97d3aadd3..ce37f5ed69 100644 --- a/spring-web/src/test/java/org/springframework/web/bind/annotation/RequestMappingReflectiveProcessorTests.java +++ b/spring-web/src/test/java/org/springframework/web/bind/annotation/RequestMappingReflectiveProcessorTests.java @@ -74,6 +74,24 @@ public class RequestMappingReflectiveProcessorTests { typeHint -> assertThat(typeHint.getType()).isEqualTo(TypeReference.of(String.class))); } + @Test + void registerReflectiveHintsForMethodWithModelAttribute() throws NoSuchMethodException { + Method method = SampleController.class.getDeclaredMethod("postForm", Request.class); + processor.registerReflectionHints(hints, method); + assertThat(hints.typeHints()).satisfiesExactlyInAnyOrder( + typeHint -> assertThat(typeHint.getType()).isEqualTo(TypeReference.of(SampleController.class)), + typeHint -> { + assertThat(typeHint.getType()).isEqualTo(TypeReference.of(Request.class)); + assertThat(typeHint.getMemberCategories()).containsExactlyInAnyOrder( + MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, + MemberCategory.DECLARED_FIELDS); + assertThat(typeHint.methods()).satisfiesExactlyInAnyOrder( + hint -> assertThat(hint.getName()).isEqualTo("getMessage"), + hint -> assertThat(hint.getName()).isEqualTo("setMessage")); + }, + typeHint -> assertThat(typeHint.getType()).isEqualTo(TypeReference.of(String.class))); + } + @Test void registerReflectiveHintsForMethodWithRestController() throws NoSuchMethodException { Method method = SampleRestController.class.getDeclaredMethod("get"); @@ -177,6 +195,10 @@ public class RequestMappingReflectiveProcessorTests { void post(@RequestBody Request request) { } + @PostMapping + void postForm(@ModelAttribute Request request) { + } + @GetMapping @ResponseBody String message() {