题目
在Spring MVC中如何设计RESTful API并实现全局异常处理?
信息
- 类型:问答
- 难度:⭐⭐
考点
RESTful设计,控制器实现,全局异常处理,HTTP状态码应用
快速回答
实现要点:
- 使用
@RestController和HTTP方法注解(如@GetMapping)定义REST端点 - 通过
@ControllerAdvice+@ExceptionHandler实现全局异常处理 - 返回统一结构的错误响应(包含状态码、消息、时间戳)
- 正确使用HTTP状态码(如404、400、500)
原理说明
Spring MVC通过DispatcherServlet处理请求,RESTful控制器需遵循:
- 无状态通信
- 资源URI语义化(如
/api/users/{id}) - 正确使用HTTP动词
- 全局异常处理通过
ControllerAdvice拦截所有控制器异常
代码示例
1. RESTful控制器
@RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
User user = userService.findById(id)
.orElseThrow(() -> new ResourceNotFoundException("User not found"));
return ResponseEntity.ok(user);
}
}2. 自定义异常
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String message) {
super(message);
}
}3. 全局异常处理器
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorResponse> handleNotFound(
ResourceNotFoundException ex, HttpServletRequest request) {
ErrorResponse error = new ErrorResponse(
LocalDateTime.now(),
HttpStatus.NOT_FOUND.value(),
"NOT_FOUND",
ex.getMessage(),
request.getRequestURI()
);
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ErrorResponse> handleValidation(
MethodArgumentNotValidException ex) {
// 处理参数校验错误(示例略)
}
}
// 统一错误响应结构
public record ErrorResponse(
LocalDateTime timestamp,
int status,
String error,
String message,
String path
) {}最佳实践
- 异常分类处理:业务异常(如ResourceNotFoundException)返回4xx,系统异常返回5xx
- 响应标准化:所有错误返回统一结构的JSON(包含时间戳、状态码、错误类型)
- HTTP状态码:
- 404:资源不存在
- 400:请求参数错误
- 500:服务器内部错误
- 日志记录:在
@ExceptionHandler中记录异常堆栈
常见错误
- 错误1:忘记
@ControllerAdvice注解导致全局处理失效 - 错误2:返回200状态码包裹错误信息(应直接使用4xx/5xx)
- 错误3:异常处理器未覆盖
Exception.class导致未知异常暴露给客户端 - 错误4:路径变量类型不匹配(如
@PathVariable String id但传入数字)触发400但无明确消息
扩展知识
- ResponseEntity:可精细控制HTTP响应头/状态码
- @ResponseStatus:在自定义异常类上定义默认HTTP状态码
- HandlerExceptionResolver:底层异常处理接口,可自定义实现
- Spring Security集成:认证异常需在安全过滤器中处理