【Controller】Spring MVC 对 Servlet 的封装
·
目录
Controller 是 Spring MVC 对 Servlet 的封装,让开发者不用手动处理 HTTP 请求,专注于业务逻辑。
一、先回顾 Servlet 的问题
Servlet 的代码
@WebServlet("/api/user/register")
public class UserServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 1. 手动获取请求体
BufferedReader reader = req.getReader();
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
String json = sb.toString();
// 2. 手动解析 JSON
JSONObject jsonObject = JSON.parseObject(json);
String account = jsonObject.getString("account");
String username = jsonObject.getString("username");
String password = jsonObject.getString("password");
// 3. 手动创建对象
User user = new User();
user.setAccount(account);
user.setUsername(username);
user.setPassword(password);
// 4. 手动调用 Service
UserService userService = new UserService();
userService.register(user);
// 5. 手动返回响应
resp.setContentType("application/json");
resp.getWriter().println("{\"code\":200,\"msg\":\"注册成功\"}");
}
}
问题清单
| 问题 | 描述 |
|---|---|
| 手动获取参数 | req.getParameter("account") |
| 手动解析 JSON | JSON.parseObject(json) |
| 手动返回响应 | resp.getWriter().println(...) |
| 代码繁琐 | 每个接口都要写大量重复代码 |
二、Controller 是什么
一句话定义
Controller 是 Spring MVC 对 Servlet 的封装,用于接收 HTTP 请求并返回响应。
Controller 在哪里
前端请求
↓
Controller(接收请求,返回响应)
↓
Service(业务逻辑)
↓
Mapper(数据库操作)
↓
数据库
Controller vs Servlet
| 对比项 | Servlet | Controller |
|---|---|---|
| 技术 | Java Web 原生技术 | Spring MVC 封装 |
| 获取参数 | req.getParameter() |
@RequestParam、@RequestBody |
| 返回响应 | resp.getWriter() |
@ResponseBody |
| 路由映射 | @WebServlet |
@RequestMapping |
| 使用场景 | 底层技术 | 实际开发推荐 |
三、Controller 怎么解决问题
对比一下
Servlet(手动):
@WebServlet("/api/user/register")
public class UserServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 手动获取参数
String account = req.getParameter("account");
String password = req.getParameter("password");
// 手动调用 Service
UserService userService = new UserService();
userService.register(account, password);
// 手动返回响应
resp.setContentType("application/json");
resp.getWriter().println("{\"code\":200}");
}
}
Controller(自动):
@RestController
@RequestMapping("/api/user")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/register")
public Result register(@RequestBody RegisterDTO dto) {
// 自动获取参数(通过 @RequestBody)
// 自动调用 Service
// 自动返回响应(通过 @ResponseBody)
return userService.register(dto);
}
}
Controller 帮你做了什么
| 功能 | Servlet(手动) | Controller(自动) |
|---|---|---|
| 获取请求参数 | req.getParameter() |
@RequestParam、@RequestBody |
| 获取路径参数 | req.getPathInfo() |
@PathVariable |
| 获取请求头 | req.getHeader() |
@RequestHeader |
| 返回响应 | resp.getWriter() |
@ResponseBody |
| 返回 JSON | 手动拼接字符串 | 自动转换(Jackson) |
| 路由映射 | @WebServlet |
@RequestMapping |
四、Spring MVC 如何封装 Servlet
封装层次
Servlet(底层)
↓
Spring MVC 封装
↓
Controller(你用的)
具体封装了什么
| Servlet(底层) | Controller(封装后) |
|---|---|
HttpServletRequest req |
@RequestBody RegisterDTO dto |
req.getParameter("account") |
dto.getAccount() |
resp.getWriter().println(...) |
return Result.success() |
| 手动解析请求参数 | 自动解析(通过注解) |
| 手动返回响应 | 自动返回(通过 @ResponseBody) |
注解对应关系
| Servlet | Controller | 作用 |
|---|---|---|
@WebServlet("/api/user") |
@RequestMapping("/api/user") |
路径映射 |
doPost() |
@PostMapping |
处理 POST 请求 |
doGet() |
@GetMapping |
处理 GET 请求 |
req.getParameter() |
@RequestParam |
获取查询参数 |
req.getReader() |
@RequestBody |
获取请求体 |
resp.getWriter() |
@ResponseBody |
返回响应 |
五、核心注解详解
1. @RestController
标记这是一个 Controller,自动返回 JSON:
@RestController // 等价于 @Controller + @ResponseBody
public class UserController {
// ...
}
2. @RequestMapping
定义路径前缀:
@RestController
@RequestMapping("/api/user") // 路径前缀
public class UserController {
// 所有接口路径都以 /api/user 开头
}
3. @PostMapping / @GetMapping
处理不同类型的请求:
@PostMapping("/register") // 处理 POST /api/user/register
public Result register(@RequestBody RegisterDTO dto) {
// ...
}
@GetMapping("/{id}") // 处理 GET /api/user/{id}
public Result getUser(@PathVariable Long id) {
// ...
}
4. @RequestBody
自动把 JSON 请求体转换成 Java 对象:
@PostMapping("/register")
public Result register(@RequestBody RegisterDTO dto) {
// dto 已经自动填充好了
System.out.println(dto.getAccount()); // zhangsan
System.out.println(dto.getUsername()); // 张三
}
5. @PathVariable
获取路径参数:
@GetMapping("/{id}")
public Result getUser(@PathVariable Long id) {
// id = 路径中的值
// 例如:GET /api/user/123 → id = 123
}
6. @RequestParam
获取查询参数:
@GetMapping("/list")
public Result list(@RequestParam String name, @RequestParam Integer page) {
// GET /api/user/list?name=张三&page=1
// name = "张三", page = 1
}
六、完整示例
用户注册接口
@RestController
@RequestMapping("/api/user")
public class UserController {
@Autowired
private UserService userService;
/**
* 用户注册
* POST /api/user/register
*/
@PostMapping("/register")
public Result register(@Valid @RequestBody RegisterDTO dto) {
return userService.register(dto);
}
/**
* 用户登录
* POST /api/user/login
*/
@PostMapping("/login")
public Result login(@Valid @RequestBody LoginDTO dto) {
return userService.login(dto);
}
/**
* 查询用户信息
* GET /api/user/{id}
*/
@GetMapping("/{id}")
public Result getUser(@PathVariable Long id) {
return userService.getUser(id);
}
/**
* 更新用户信息
* PUT /api/user
*/
@PutMapping
public Result updateUser(
@RequestHeader("Authorization") String token,
@RequestBody UpdateUserDTO dto) {
Long userId = getUserIdFromToken(token);
return userService.updateUser(userId, dto);
}
}
对应的 Service
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public Result register(RegisterDTO dto) {
// 1. 检查账号是否已存在
User existing = userMapper.findByAccount(dto.getAccount());
if (existing != null) {
return Result.error(400, "账号已存在");
}
// 2. 创建用户
User user = new User();
user.setAccount(dto.getAccount());
user.setUsername(dto.getUsername());
user.setPassword(encrypt(dto.getPassword()));
// 3. 保存到数据库
userMapper.insert(user);
return Result.success("注册成功");
}
}
七、总结
Controller 解决的问题
| 问题 | Servlet | Controller |
|---|---|---|
| 获取参数 | 手动 | 自动(注解) |
| 解析 JSON | 手动 | 自动(@RequestBody) |
| 返回响应 | 手动 | 自动(@ResponseBody) |
| 路由映射 | @WebServlet | @RequestMapping |
一句话总结
Controller 是 Spring MVC 对 Servlet 的封装,它自动处理 HTTP 请求解析和响应构建,让开发者专注于业务逻辑。
参考资料:
更多推荐



所有评论(0)