How do @Controller and @RestController relate to stereotype annotations, and what does @RestController add?
answer
- @Controller = @Component + MVC routing
- @RestController = @Controller + @ResponseBody
- @ResponseBody -> HttpMessageConverters serialize body (JSON)
- @Controller default return = view name
- composed annotation example
basics
~20 s@Controller is a @Component specialization Spring MVC detects to route web requests to handler methods. @RestController is a composed annotation = @Controller + @ResponseBody, so every handler's return value is serialized directly to the response body (typically JSON) instead of resolving a view.
solid answer
~40 s@Controller (org.springframework.stereotype.Controller) is a stereotype specialization of @Component; besides being registered as a bean, Spring MVC's RequestMappingHandlerMapping recognizes it and maps its @RequestMapping/@GetMapping methods to HTTP requests. By default a @Controller method's String return value is treated as a view name resolved by a ViewResolver. @RestController (org.springframework.web.bind.annotation.RestController) is itself meta-annotated with @Controller and @ResponseBody — a composed annotation. @ResponseBody makes each handler's return value written directly to the HTTP response body via HttpMessageConverters (e.g., Jackson to JSON) rather than resolved as a view. So @RestController is the idiomatic choice for REST/JSON APIs, while @Controller suits server-rendered views (Thymeleaf) — where you'd add @ResponseBody selectively for API methods.
code
java · 21 linesimport org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
@RestController // = @Controller + @ResponseBody
@RequestMapping("/api/users")
class UserApi {
@GetMapping("/{id}")
User get(@PathVariable Long id) {
return new User(id, "Ada"); // serialized to JSON, not a view
}
}
@Controller // server-rendered views
class PageController {
@GetMapping("/home")
String home(Model model) {
model.addAttribute("title", "Home");
return "home"; // resolved to a view template named "home"
}
}go deeper
Know @RestController is for JSON APIs and @Controller for web pages.
Explain @RestController = @Controller + @ResponseBody and the view-name vs body-serialization difference.
Discuss HttpMessageConverters/content negotiation and the composed-annotation mechanics.
Cite it as the canonical meta-annotation-composition example and reason about API vs MVC layering conventions.
**`@Controller`** (`org.springframework.stereotype.Controller`) is a stereotype: it's meta-annotated with `@Component`, so component scanning registers the class as a bean. Its special role is in **Spring MVC**: `RequestMappingHandlerMapping` specifically looks for beans annotated with `@Controller` and inspects them for `@RequestMapping` (and shortcuts `@GetMapping`, `@PostMapping`, etc.) to build the URL-to-method routing table. A plain `@Component` is **not** treated as a web controller. **Default view semantics:** in a classic `@Controller`, a handler that returns a `String` is interpreted as a **logical view name**, passed to a `ViewResolver` (e.g., Thymeleaf/JSP) to render HTML. Model data is added via a `Model`/`ModelAndView`. **`@ResponseBody`:** placing `@ResponseBody` on a handler method (or its return) tells Spring MVC to skip view resolution and instead serialize the return value straight into the HTTP response body using registered **`HttpMessageConverter`s** — e.g., `MappingJackson2HttpMessageConverter` for JSON, based on content negotiation. **`@RestController`** (`org.springframework.web.bind.annotation.RestController`) is a **composed annotation**: it is meta-annotated with both `@Controller` and `@ResponseBody`. Therefore: - It's a stereotype (scanned as a bean) and an MVC controller. - Every handler method implicitly has `@ResponseBody`, so return values are serialized to the body (JSON by default). No view resolution. **When to use which:** - **`@RestController`** — REST/JSON (or XML) APIs returning data objects. - **`@Controller`** — server-side rendered pages; add `@ResponseBody` on the specific methods that should return raw data. **Gotchas:** - Because `@RestController` includes `@ResponseBody`, returning a `String` from it writes the literal string as the body (text), **not** a view name — a common surprise when migrating from `@Controller`. - Both still require component scanning to reach the class's package. - `@RestController` is a great real-world example of Spring's meta-annotation composition pattern (same mechanism used by custom stereotypes). - For error handling, `@ControllerAdvice`/`@RestControllerAdvice` follow the same composition (the latter adds `@ResponseBody`).
- You return the String "users" from a @RestController method. What happens?It's written to the response body as the literal text "users" (because @ResponseBody is implied), not resolved as a view named users.
- Is @RestController a stereotype? Why?Yes — it is meta-annotated with @Controller, which is meta-annotated with @Component, so it is transitively a @Component and is picked up by component scanning.
saying these in an interview costs you the question
- Saying @RestController resolves view names
- Thinking a plain @Component can serve MVC requests
- Claiming @RestController is unrelated to @Controller
- Believing @ResponseBody is required per-method on a @RestController