Skip to content

Commit 1800b10

Browse files
committed
Expose parameter annotations from interfaces across entire class hierarchy
Closes gh-24127
1 parent 7ebd850 commit 1800b10

File tree

2 files changed

+33
-3
lines changed

2 files changed

+33
-3
lines changed

spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -352,7 +352,7 @@ private List<Annotation[][]> getInterfaceParameterAnnotations() {
352352
List<Annotation[][]> parameterAnnotations = this.interfaceParameterAnnotations;
353353
if (parameterAnnotations == null) {
354354
parameterAnnotations = new ArrayList<>();
355-
for (Class<?> ifc : this.method.getDeclaringClass().getInterfaces()) {
355+
for (Class<?> ifc : ClassUtils.getAllInterfacesForClassAsSet(this.method.getDeclaringClass())) {
356356
for (Method candidate : ifc.getMethods()) {
357357
if (isOverrideFor(candidate)) {
358358
parameterAnnotations.add(candidate.getParameterAnnotations());

spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -690,6 +690,27 @@ public void resolveArgumentTypeVariableWithGenericInterface() throws Exception {
690690

691691
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
692692

693+
assertThat(processor.supportsParameter(methodParameter)).isTrue();
694+
String value = (String) processor.readWithMessageConverters(
695+
this.request, methodParameter, methodParameter.getGenericParameterType());
696+
assertThat(value).isEqualTo("foo");
697+
}
698+
699+
@Test // gh-24127
700+
public void resolveArgumentTypeVariableWithGenericInterfaceAndSubclass() throws Exception {
701+
this.servletRequest.setContent("\"foo\"".getBytes("UTF-8"));
702+
this.servletRequest.setContentType(MediaType.APPLICATION_JSON_VALUE);
703+
704+
Method method = SubControllerImplementingInterface.class.getMethod("handle", Object.class);
705+
HandlerMethod handlerMethod = new HandlerMethod(new SubControllerImplementingInterface(), method);
706+
MethodParameter methodParameter = handlerMethod.getMethodParameters()[0];
707+
708+
List<HttpMessageConverter<?>> converters = new ArrayList<>();
709+
converters.add(new MappingJackson2HttpMessageConverter());
710+
711+
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
712+
713+
assertThat(processor.supportsParameter(methodParameter)).isTrue();
693714
String value = (String) processor.readWithMessageConverters(
694715
this.request, methodParameter, methodParameter.getGenericParameterType());
695716
assertThat(value).isEqualTo("foo");
@@ -1041,4 +1062,13 @@ default A handle(@RequestBody A arg) {
10411062
static class MyControllerImplementingInterface implements MappingInterface<String> {
10421063
}
10431064

1065+
1066+
static class SubControllerImplementingInterface extends MyControllerImplementingInterface {
1067+
1068+
@Override
1069+
public String handle(String arg) {
1070+
return arg;
1071+
}
1072+
}
1073+
10441074
}

0 commit comments

Comments
 (0)