Foundation · Build
@RestController vs @Controller
@Controller returns view names unless @ResponseBody opts a method into message conversion; @RestController bakes that opt-in in for the whole class.
Primary source: Spring MVC: @RestController & @ResponseBody
Lesson 3 of 11
1d streakThe Architectural Question
Returning a DTO from @Controller without @ResponseBody sends Spring hunting for a view template named after your object instead of writing JSON to the socket.
What this guide proves
- @RestController
- @RequestMapping
- MessageConverters
Legacy XML MVC Configuration vs Modern Annotations
Before Spring Boot auto-configuration and the @RestController annotation, configuring Spring MVC required extensive XML. You had to explicitly declare the DispatcherServlet in web.xml and map handler components in a separate Spring XML context.
<!-- Legacy XML approach to Spring MVC -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="...">
<!-- 1. Enable MVC annotation driven features -->
<mvc:annotation-driven/>
<!-- 2. Scan for @Controller components -->
<context:component-scan base-package="com.example.controllers"/>
</beans>Architectural Boundary · Do Not Confuse
XML <mvc:annotation-driven/>
@RestController and Spring Boot
In the past, you explicitly wired MVC components. Today, Spring Boot detects Tomcat and automatically registers DispatcherServlet and Jackson message converters without a single line of XML.
@RestController vs @Controller: View resolution vs message conversion
The difference between @Controller and @RestController is not cosmetic; it alters how Spring MVC handles method return values.
Architectural Boundary · Do Not Confuse
@Controller (HTML Template Mode)
@RestController (REST API Mode)
@Controller expects return values to be view template names (e.g. "index" -> index.html via Thymeleaf). @RestController is meta-annotated with @ResponseBody, instructing Spring to serialize the return object directly into JSON/XML via HttpMessageConverters without view resolution.
| Annotation | Meta-Annotations | Return Value Interpretation | Typical Use Case |
|---|---|---|---|
| @Controller | @Component | String = View template name; Model passed to template engine | Server-rendered web pages (Thymeleaf, FreeMarker, JSP) |
| @RestController | @Controller + @ResponseBody | Object serialized into response body via Jackson | REST APIs, JSON/XML web services, Mobile/SPA backends |
@RestController // Combines @Controller + @ResponseBody
@RequestMapping("/api/v1/tasks")
public class TaskApiController {
@GetMapping("/{id}")
public TaskDto getTask(@PathVariable Long id) {
return new TaskDto(id, "Read the Web module"); // Serialized to JSON automatically!
}
}The HttpMessageConverter serialization pipeline
When a method in a @RestController returns an object, Spring's RequestResponseBodyMethodProcessor iterates through the registered HttpMessageConverter list to find a converter matching the requested Accept header and return type:
- 01ByteArrayHttpMessageConverter: Handles byte[] payloads.
- 02StringHttpMessageConverter: Handles raw text/plain strings.
- 03ResourceHttpMessageConverter: Handles file downloads and streamable resources.
- 04MappingJackson2HttpMessageConverter: Handles JSON serialization via Jackson ObjectMapper.
Break it deliberately: Circular view resolution error on @Controller
Returning a String from a class annotated with @Controller (instead of @RestController) tricks Spring MVC into treating the string as a template file name.
@Controller // Mistake: intended to return REST data!
@RequestMapping("/api/status")
public class StatusController {
@GetMapping
public String getStatus() {
return "UP"; // Spring searches for a template named "UP.html"!
}
}HTTP/1.1 500 Internal Server Error org.springframework.web.servlet.DispatcherServlet - Error resolving template [UP], template might not exist or might not be accessible jakarta.servlet.ServletException: Circular view path [UP]: would dispatch back to the current handler URL [/api/status] again.
The Fix
Check your understanding
Active Recall Checkpoint
What composed annotation combines @Controller with class-level @ResponseBody?
Hint: Think about response payload writing.
Show answer & explanation
@RestController is the composed annotation: it combines @Controller and class-level @ResponseBody. Adding @ResponseBody to a method opts that method into message conversion without changing the class annotation.
Active Recall Checkpoint
Why does returning a String from a @Controller without @ResponseBody cause a circular view path exception?
Hint: What does the ViewResolver do with the string?
Show answer & explanation
Spring treats the returned string as a view template name. If no template engine handles it, Spring forwards to that path as a servlet resource, resulting in circular dispatch back to the handler.
Synthesis & Production Verification
Production Acceptance Criteria
- Explain what @ResponseBody changes about return-value handling
- Convert a view-returning controller into a data controller
- Map GET and POST routes with @GetMapping and @PostMapping
Key Takeaway
@RestController combines @Controller and @ResponseBody, bypassing view resolution and delegating return values directly to HttpMessageConverters.
Architectural & Technical Review
Core Interview Questions
Q01What is the architectural distinction between @Controller and @RestController?Show answer
@Controller returns view names resolved by ViewResolvers to render HTML templates. @RestController has @ResponseBody meta-annotated, writing serialized JSON/XML bytes directly to the HTTP socket.
Q02Which component coordinates return value serialization in Spring MVC?Show answer
RequestResponseBodyMethodProcessor inspects the Accept header and return type, selecting an HttpMessageConverter (like Jackson) to write the response payload.
Q03Why does removing @ResponseBody from a DTO endpoint produce a circular view error?Show answer
Spring attempts to resolve the endpoint URI as an internal view template name, resulting in a recursive forward loop back to the same path.
Production Pitfalls
Critical Anti-Patterns
- Pitfall: Mixing view templates with JSON APIs in one controller — Combine @ResponseBody with standard view resolution only when strictly necessary; prefer dedicated @RestController classes for APIs.
- Pitfall: Returning raw collections without encapsulation — Returning top-level JSON arrays limits future response metadata additions; prefer container objects or records.
Primary Documentation & Specifications
Lesson Primary References
Supplementary Module Resources