With multiple Spring controllers that consume and produce application/json
, my code is littered with long annotations like:
@RequestMapping(value = "/foo", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
Is there a way to produce a "composite/inherited/aggregated" annotation with default values for consumes
and produces
, such that I could instead write something like:
@JSONRequestMapping(value = "/foo", method = RequestMethod.POST)
How do we define something like @JSONRequestMapping
above? Notice the value
and method
passed in just like in @RequestMapping
, also good to be able to pass in consumes
or produces
if the default isn't suitable.
I need to control what I'm returning. I want the produces
/consumes
annotation-methods so that I get the appropriate Content-Type
headers.
You can also consume the object with the requested media type using the consumes element of@RequestMapping in combination with the @RequestBody annotation. The code to use producible and consumable with @RequestMapping is this. In this code, the getProduces() handler method produces a JSON response.
Create a simple Spring Boot web application and write a controller class files which is used to redirects into the HTML file to consumes the RESTful web services. We need to add the Spring Boot starter Thymeleaf and Web dependency in our build configuration file. For Maven users, add the below dependencies in your pom.
RequestMapping annotation is used to map web requests onto specific handler classes and/or handler methods. @RequestMapping can be applied to the controller class as well as methods. Today we will look into various usage of this annotation with example and other annotations @PathVariable and @RequestParam .
@RequestMapping is used at the class level while @GetMapping is used to connect the methods. This is also an important Spring MVC interview question to knowing how and when to use both RequestMapping and GetMapping is crucial for Java developers.
As of Spring 4.2.x, you can create custom mapping annotations, using @RequestMapping
as a meta-annotation. So:
Is there a way to produce a "composite/inherited/aggregated" annotation with default values for consumes and produces, such that I could instead write something like:
@JSONRequestMapping(value = "/foo", method = RequestMethod.POST)
Yes, there is such a way. You can create a meta annotation like following:
@Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @RequestMapping(consumes = "application/json", produces = "application/json") public @interface JsonRequestMapping { @AliasFor(annotation = RequestMapping.class, attribute = "value") String[] value() default {}; @AliasFor(annotation = RequestMapping.class, attribute = "method") RequestMethod[] method() default {}; @AliasFor(annotation = RequestMapping.class, attribute = "params") String[] params() default {}; @AliasFor(annotation = RequestMapping.class, attribute = "headers") String[] headers() default {}; @AliasFor(annotation = RequestMapping.class, attribute = "consumes") String[] consumes() default {}; @AliasFor(annotation = RequestMapping.class, attribute = "produces") String[] produces() default {}; }
Then you can use the default settings or even override them as you want:
@JsonRequestMapping(method = POST) public String defaultSettings() { return "Default settings"; } @JsonRequestMapping(value = "/override", method = PUT, produces = "text/plain") public String overrideSome(@RequestBody String json) { return json; }
You can read more about AliasFor
in spring's javadoc and github wiki.
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