Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
spring-projects-issues opened this issue Dec 22, 2016 · 1 comment
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) status: duplicate A duplicate of another issue type: enhancement A general enhancement

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Dec 22, 2016

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:

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Dec 23, 2016

Juergen Hoeller commented

This seems like a duplicate of #15682 which we intend to address for 5.0 RC1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) status: duplicate A duplicate of another issue type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants