diff --git a/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java b/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java index 4a59b407ff..a8feb6e405 100644 --- a/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java +++ b/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -339,7 +339,7 @@ public class HandlerMethod { List parameterAnnotations = this.interfaceParameterAnnotations; if (parameterAnnotations == null) { parameterAnnotations = new ArrayList<>(); - for (Class ifc : this.method.getDeclaringClass().getInterfaces()) { + for (Class ifc : ClassUtils.getAllInterfacesForClassAsSet(this.method.getDeclaringClass())) { for (Method candidate : ifc.getMethods()) { if (isOverrideFor(candidate)) { parameterAnnotations.add(candidate.getParameterAnnotations()); diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java index 9a44139517..47c622b6cc 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -703,6 +703,27 @@ public class RequestResponseBodyMethodProcessorTests { RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters); + assertTrue(processor.supportsParameter(methodParameter)); + String value = (String) processor.readWithMessageConverters( + this.request, methodParameter, methodParameter.getGenericParameterType()); + assertEquals("foo", value); + } + + @Test // gh-24127 + public void resolveArgumentTypeVariableWithGenericInterfaceAndSubclass() throws Exception { + this.servletRequest.setContent("\"foo\"".getBytes("UTF-8")); + this.servletRequest.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE); + + Method method = SubControllerImplementingInterface.class.getMethod("handle", Object.class); + HandlerMethod handlerMethod = new HandlerMethod(new SubControllerImplementingInterface(), method); + MethodParameter methodParameter = handlerMethod.getMethodParameters()[0]; + + List> converters = new ArrayList<>(); + converters.add(new MappingJackson2HttpMessageConverter()); + + RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters); + + assertTrue(processor.supportsParameter(methodParameter)); String value = (String) processor.readWithMessageConverters( this.request, methodParameter, methodParameter.getGenericParameterType()); assertEquals("foo", value); @@ -1055,4 +1076,13 @@ public class RequestResponseBodyMethodProcessorTests { static class MyControllerImplementingInterface implements MappingInterface { } + + static class SubControllerImplementingInterface extends MyControllerImplementingInterface { + + @Override + public String handle(String arg) { + return arg; + } + } + }