Skip to content

Allow controller parameter annotations (@RequestBody, @PathVariable...) to be defined on interfaces or parent classes [SPR-15046] #19612

Closed
@spring-projects-issues

Description

@spring-projects-issues

Kiril Karaatanassov opened SPR-15046 and commented

We are trying to use external REST API definition that would generate interfaces one implements in Java. For the time being we try to use Swagger.

Unfortunately Spring does not allow us to separate the API definition from implementation as the parameter annotations on controllers are not read from interfaces. Instead of that Spring always looks into the concrete implementation whose purpose is to implement a contract not define it. Weirdly enough the @RequestMapping annotation can be declared on the interface and is picked up by the implementing controller. It would be great if similar functionality is provided for @RequestBody, @PathVariable, @RequestHeader etc. that are defined on the individual parameters.

It seems that a potential fix has to update/extend the implementation of

Annotation[] org.springframework.core.MethodParameter.getParameterAnnotations()

this is called by

MethodParameter[] org.springframework.web.method.HandlerMethod.initMethodParameters()

called by
org.springframework.web.method.HandlerMethod constructor which in turn is called by

org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.createHandlerMethod(Object, Method).

There is a sample but hacky workaround found on StackOverflow. See

http://stackoverflow.com/questions/8002514/spring-mvc-annotated-controller-interface/8005644#8005644

It does require some creativity to put in practical use with Spring Boot i.e. WebMvcRegistrations

So the basic ask is to pick up parameter annotations for controller from implemented interfaces e.g.

public interface MyControllerInterface {

    @RequestMapping(path="/test", method=RequestMethod.POST)
    public ResponseEntity<String> echo(@RequestBody String input);

}

@RestController
public class MyControllerImpl implements MyControllerInterface {
    @Override
    public ResponseEntity<String> echo(String input) {
        return new ResponseEntity<>(input, HttpStatus.OK);
    }
}

It may make sense to to use @RestController or alike annotation on the interfaces whose methods will be checked.

PS I filed this to Spring Boot and was redirected here spring-projects/spring-boot#7730


Affects: 4.3 GA

Issue Links:

Metadata

Metadata

Assignees

Labels

in: webIssues in web modules (web, webmvc, webflux, websocket)status: duplicateA duplicate of another issuetype: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions