Spring MVC
约 635 字大约 2 分钟
布欧-Lewyon
2026-05-16
首页 › Java › Spring › Spring MVC
Spring MVC 基于 Servlet API 构建,提供注解驱动的 Web 开发模型。@Controller/@RestController 处理请求,将请求数据绑定到方法参数,并处理异常。
核心流程
请求 → DispatcherServlet(前端控制器)
→ HandlerMapping(匹配 URL → Controller 方法)
→ Controller 方法执行
→ 返回 ModelAndView / @ResponseBody
→ ViewResolver 解析视图 / HttpMessageConverter 写 JSON
→ 响应DispatcherServlet 是 Spring MVC 的核心,它本身是一个 Servlet,负责将请求分派给对应的处理器。
@RestController
@RestController
@RequestMapping("/api/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping
public List<User> getAll() {
return userService.findAll();
}
@GetMapping("/{id}")
public User getById(@PathVariable Long id) {
return userService.findById(id);
}
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public User create(@RequestBody @Valid User user) {
return userService.save(user);
}
@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void delete(@PathVariable Long id) {
userService.deleteById(id);
}
}@RestController=@Controller+@ResponseBody,方法返回值直接序列化为 JSON,不走视图解析。@RequestMapping及其简写变体:@GetMapping/@PostMapping/@PutMapping/@DeleteMapping/@PatchMapping。
参数绑定
// 路径变量
@GetMapping("/users/{id}")
public User get(@PathVariable Long id)
// 查询参数
@GetMapping("/users")
public List<User> search(@RequestParam(required = false) String name,
@RequestParam(defaultValue = "0") int page)
// 请求体
@PostMapping("/users")
public User create(@RequestBody @Valid User user)
// 请求头
@GetMapping("/header")
public String header(@RequestHeader("User-Agent") String ua)参数校验
Spring Boot 集成 Bean Validation(jakarta.validation),在 DTO 上声明约束:
public class CreateUserRequest {
@NotBlank(message = "用户名不能为空")
@Size(min = 2, max = 20)
private String name;
@NotBlank
@Email
private String email;
@Min(1) @Max(150)
private int age;
}Controller 中的 @Valid 或 @Validated 触发校验,校验失败时抛出 MethodArgumentNotValidException。
异常处理
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public ErrorResponse handleNotFound(ResourceNotFoundException ex) {
return new ErrorResponse(404, ex.getMessage());
}
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ErrorResponse handleValidation(MethodArgumentNotValidException ex) {
String msg = ex.getBindingResult().getFieldErrors().stream()
.map(e -> e.getField() + ": " + e.getDefaultMessage())
.collect(Collectors.joining(", "));
return new ErrorResponse(400, msg);
}
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ErrorResponse handleGeneral(Exception ex) {
return new ErrorResponse(500, "服务器内部错误");
}
}@RestControllerAdvice全局统一处理异常,避免每个 Controller 都写try-catch。- 异常处理方法的匹配范围:精确异常类型优先于通用类型。
小结
- Spring MVC 以
DispatcherServlet为核心,@RestController配合@RequestMapping处理 RESTful 请求。 - 参数绑定:
@PathVariable(路径)、@RequestParam(查询)、@RequestBody(请求体)、@RequestHeader(请求头)。 - 校验用
@Valid+ Bean Validation 注解(@NotBlank/@Email/@Min等),@RestControllerAdvice全局处理异常。 - 易错:
@RequestBody只能有一个,且不能与@RequestParam在同一方法中混用读取请求体。另外,@Transactional在 Controller 层无效——应该在 Service 层使用。 - 思考任务:创建一个完整的
TodoController(GET/POST/PUT/DELETE),添加参数校验和全局异常处理,用 Postman 或 curl 测试所有端点。
上一节:Spring 核心
下一节:Spring 数据访问
