I have properly working Spring Controller, where I have a method mapped in a following way
@RequestMapping(
value = "/users"
consumes = MimeTypeUtils.APPLICATION_JSON_VALUE,
produces = MimeTypeUtils.APPLICATION_JSON_VALUE,
method = RequestMethod.GET)
@ResponseBody
@ResponseStatus(HttpStatus.OK)
public UserResponse retrieveUsers() {
return new UserResponse();
}
@RequestMapping(
value = "/contracts"
consumes = MimeTypeUtils.APPLICATION_JSON_VALUE,
produces = MimeTypeUtils.APPLICATION_JSON_VALUE,
method = RequestMethod.GET)
@ResponseBody
@ResponseStatus(HttpStatus.OK)
public ContractResponse retrieveContracts() {
return new ContractResponse();
}
This works fine, GET requests are served as accepted, and in case of for example POST I am receiving proper 405 status code.
Now I want to introduce custom combined annotation, not to have the same bunch of annotations in each and every method.
My custom annotation looks like,
@RequestMapping(
consumes = MimeTypeUtils.APPLICATION_JSON_VALUE,
produces = MimeTypeUtils.APPLICATION_JSON_VALUE,
method = RequestMethod.GET)
@ResponseBody
@ResponseStatus(HttpStatus.OK)
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Get {}
Accordingly, I change the method to
@Get
@RequestMapping(value = "/users")
public UserResponse retrieveUsers() {
return new UserResponse();
}
In this case I can see that whatever type of request I send to /users it is served properly. For example even if I do POST, I see response. So the @RequestMapping does not work properly.
What am I doing wrong here? Is it possible to make controllers behave properly with custom combined annotation?
I suspect that the @RequestMapping(value = "/users") on UserResponse#retrieveUsers replaces the @RequestMapping on the @Get interface.
See if this works:
@RequestMapping(
consumes = MimeTypeUtils.APPLICATION_JSON_VALUE,
produces = MimeTypeUtils.APPLICATION_JSON_VALUE,
method = RequestMethod.GET)
@ResponseBody
@ResponseStatus(HttpStatus.OK)
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Get {
@AliasFor(annotation = RequestMapping.class, attribute = "value")
String[] value() default {};
}
@Get(value = "/users")
public UserResponse retrieveUsers() {
return new UserResponse();
}
You may be interested in GetJson in the spring-composed project.
Note that @AliasFor was only released with Spring 4.2. It's not available in earlier versions.
You overwrite the @RequestMapping annotation you had set up in your @Get annotation. Therefore it specifies only the value part of the request mapping, leaving all other properties to default.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With