Spring @RestController: should I need to indicate produces = MediaType.APPLICATION_JSON_VALUE in a method explicitely

Viewed 903

As the title says, I wonder if I still need to declare produces = MediaType.APPLICATION_JSON_VALUE in a controller's method if the controller is already annotated with @RestController? I'm working on an old legacy application where all the controller methods have this declared. Spring Boot Initializr generates a default REST controller without it and even if I omit MediaType.APPLICATION_JSON_VALUE, it still works without any problems. I remember to have seen somewhere that is supposed to be as default. Correct or not?

@RestController
@RequestMapping("/posts")
@Slf4j
public class PostsController {

    @PutMapping(value = "posts/{post_d}", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Post> getPost(@PathVariable Long postId) {
      ...
    }
}
2 Answers

The first thing to acknowledge/remember is that everything in the @RequestMapping annotation (or the specialized @GetMapping, @PostMapping, etc. ) is that it is used for mapping. Hence the fact that that thing is named @RequestMapping. It does not force anything upon the response being written. In fact the produces attribute actually takes an String[] so that you can limit for which response types (the Accept-Header) this method will match. So if you do produces = MediaType.APPLICATION_JSON_VALUE only requests that explicitly accept application/json in their response will go to this method.

The fact that it is used for mapping/routing makes it useful to have multiple methods for the same URL but producing different results. Lets say you have a request method that produces a report which can be created in XML or PDF. But the PDF is more complex so you need a different method.

@RequestMapping(value="/report", produces = "application/xml")
public ReportXml generateXmlReport() {}

@RequestMapping(value="/report", produces = "application/pdf")
public void generateXmlReport(HttpServletResponse response) {
  // use iText to generate a PDF and directly write to the response
}

Now due to the produces Spring MVC can use this to route an incoming request to the proper request handling method.

I think you should show us the error occured. Normally, it is not necessary to specify the value of produces at the controller level, but at the level of the services that consume it.

Note that the path to test this function is:

baseURL/posts/posts/{post_d}
Related