Spring MVC全局异常处理与重定向数据传递实践
异常处理机制解析
Spring MVC框架提供了多层次的异常响应转换策略。当控制器方法抛出异常时,框架会自动将特定异常类型映射为对应的HTTP状态码。若未匹配到预设映射,系统默认返回500服务器错误。关键映射关系如下:
开发者可通过@ResponseStatus注解定制业务异常的响应状态。例如定义用户不存在异常:
/**
* 自定义404异常类型
* code: HTTP状态码
* message: 错误描述信息
*/
@ResponseStatus(code = HttpStatus.NOT_FOUND, message = "用户资源不存在")
public class UserNotFoundException extends RuntimeException {
public UserNotFoundException(String userId) {
super("ID: " + userId);
}
}
对于跨控制器的全局异常处理,推荐使用@ControllerAdvice结合@ExceptionHandler。以下实现将捕获所有异常并返回标准化JSON响应:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler
@ResponseBody
public ApiResponse handleAllExceptions(Exception ex) {
return ApiResponse.error(500, "系统繁忙,请稍后重试");
}
}
控制器通知优先级问题
在Spring Boot应用中,自定义异常处理器可能因优先级问题失效。启动日志显示:
Detected @ExceptionHandler methods in systemExceptionHandler
Detected @ExceptionHandler methods in customExceptionHandler
当多个异常处理器存在时,框架会优先调用高优先级Bean。通过@Order注解提升自定义处理器优先级:
@ControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CriticalExceptionHandler {
@ExceptionHandler(NullPointerException.class)
@ResponseBody
public ApiResponse handleNullPointer(NullPointerException e) {
return ApiResponse.error(400, "请求参数异常");
}
}
重定向数据传递方案
当控制器返回redirect:/target时,需特殊处理数据传递。框架提供两种有效方式:
路径参数传递:适用于简单数据类型,通过URI模板携带参数:
@GetMapping("/profile")
public String redirectToProfile(Model model) {
model.addAttribute("userId", "U1001");
model.addAttribute("role", "admin");
return "redirect:/users/{userId}?access={role}";
}
最终生成重定向路径:/users/U1001?access=admin
闪存属性传递:适用于复杂对象,利用RedirectAttributes实现跨请求数据暂存:
@GetMapping("/submit")
public String processForm(RedirectAttributes redirectAttrs) {
UserProfile profile = new UserProfile("张三", 28);
redirectAttrs.addFlashAttribute("user", profile);
redirectAttrs.addAttribute("status", "success");
return "redirect:/result";
}
@GetMapping("/result")
public String showResult(Model model) {
// 从模型中获取闪存属性
boolean hasUser = model.containsAttribute("user"); // 返回true
return "result-page";
}
该机制底层通过会话存储实现,仅适用于同一应用内的重定向操作。