Card 04/ 06
@RestController vs @Controller: When a Returned String Becomes a 404
The same method body answers hello under one annotation and 404 under the other.
@Controller and @RestController both mark a class whose methods answer web requests, but they treat a returned value differently. @RestController sends the value back as the response body; @Controller treats a returned String as the name of a view (an HTML template) to render.
Two methods with identical bodies both return the string "hello". One answers with hello, and the other answers 404:
@RestController
class GreetingRestController {
@GetMapping("/rest-greeting")
String greet() { return "hello"; }
}
@Controller
class GreetingViewController {
@GetMapping("/view-greeting")
String greet() { return "hello"; }
}@RestController -> 200 body="hello"
@Controller -> 404 (treats "hello" as a view name to resolve)In a templated application, "hello" would resolve to a template such as hello.html. With no template engine configured, Spring has nothing to render "hello" into, and the request ends in a 404.
@RestController is @Controller with @ResponseBody added to every method, and @ResponseBody is what changes the interpretation: the return value becomes the response body itself.
The mistake is easy to make when a method moves between classes, and costly because the application starts and the method looks right; only the call itself fails.
For a JSON or text API, use @RestController. Use @Controller only when methods return template names, and if one method in such a class needs to return data, put @ResponseBody on that method alone.
← → move through sections and cards