🔎统一异常的处理
统一异常的处理, 利用 2 个注解
- @ControllerAdvice → 感知异常
- @ExceptionHandler → 处理异常
未设置异常处理🍂
NullPointerException
ArithmeticException
设置异常处理🍂
@ControllerAdvice @ResponseBody public class MyExceptionHandler { /** * 拦截所有空指针异常, 进行统一数据格式的返回 * @author bibubibu * @date 2023/7/9 */ @ExceptionHandler(NullPointerException.class) public HashMap<String, Object> nullPointerException(NullPointerException e) { HashMap<String, Object> map = new HashMap<>(); map.put("status", -1); map.put("data", null); map.put("msg", "NullPointerException" + e.getMessage()); // 错误码的描述信息 return map; } /** * 拦截所有算数异常, 进行统一数据格式的返回 * @author bibubibu * @date 2023/7/9 */ @ExceptionHandler(ArithmeticException.class) public HashMap<String, Object> arithmeticException(ArithmeticException e) { HashMap<String, Object> map = new HashMap<>(); map.put("status", -1); map.put("data", null); map.put("msg", "ArithmeticException" + e.getMessage()); // 错误码的描述信息 return map; } /** * 拦截所有异常, 进行统一数据格式的返回 * @author bibubibu * @date 2023/7/9 */ @ExceptionHandler(Exception.class) public HashMap<String, Object> exception(Exception e) { HashMap<String, Object> map = new HashMap<>(); map.put("status", -1); map.put("data", null); map.put("msg", "Exception" + e.getMessage()); return map; } }
NullPointerException
ArithmeticException
🔎统一数据格式的返回
统一数据格式返回的优点
- 方便前端程序员更好的接收和解析后端数据接口返回的数据
- 降低前端程序员和后端程序员的沟通成本, 按照某个格式实现即可, 因为所有接口都是这样返回的
- 有利于项目统一数据的维护和修改
- 有利于后端技术部门统一规范的标准制定, 不会出现奇怪的返回内容
统一数据格式返回的实现
统一数据格式的返回, 利用注解 @ControllerAdvice + ResponseBodyAdvice(接口) 实现
未设置统一数据格式的返回🍂
@RestController @RequestMapping("/user") public class UserController { @RequestMapping("get-num") public Integer getNumber() { return (int) (Math.random() * 10 + 1); } }
设置统一数据格式的返回🍂
- 自定义类(ResponseAdvice), 添加 @ControllerAdvice 注解
- 实现 ResponseBodyAdvice 接口, 重写 supports() 与 beforeBodyWrite()
supports() 类似于一个开关
当返回值为 true 时, 开启 beforeBodyWrite() 中编写的相关功能
当返回值为 false 时, 关闭 beforeBodyWrite() 中编写的相关功能
@ControllerAdvice public class ResponseAdvice implements ResponseBodyAdvice { @Override public boolean supports(MethodParameter returnType, Class converterType) { return true; } @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { HashMap<String, Object> map = new HashMap<>(); map.put("status", 200); map.put("data", body); // 此处的 Body 是 String 类型会出错 map.put("msg", ""); return map; } }
当方法的返回值类型为 String 时
@RestController @RequestMapping("/user") public class UserController { @RequestMapping("/get-user") public String getUser() { System.out.println("执行 getUser()"); return "getUser~~"; } }
当调用方法的返回值类型为 String 时, 设置统一数据格式的返回🍂
类型转换异常
解决方法
当调用方法的返回值类型为 String 时, 利用 jackson 完成类型转换
@ControllerAdvice public class ResponseAdvice implements ResponseBodyAdvice { // 利用 jackson 转换 String @Autowired private ObjectMapper objectMapper; @Override public boolean supports(MethodParameter returnType, Class converterType) { return true; } @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { HashMap<String, Object> map = new HashMap<>(); map.put("status", 200); map.put("data", body); // 此处的 Body 是 String 类型会出错 map.put("msg", ""); // 判断 Body 是否为 String 类型 if(body instanceof String) { // 是 String 类型, 将 map 转换为 Json 格式 try { return objectMapper.writeValueAsString(map); } catch (JsonProcessingException e) { e.printStackTrace(); } } return map; } }
🔎总结
- 用户登录权限的统一校验 → 实现 HandlerInterceptor 接口 + 重写 preHandler 方法 + 将自定义拦截器添加至配置文件中(实现 WebMvcConfigurer 接口)
- 统一访问前缀的添加 → 重写 configurePathMatch( ) / 在配置文件中添加
- 统一异常的处理 → 利用注解 @ControllerAdvice + @ExceptionHandler
- 统一数据格式的返回 → 利用注解 @ControllerAdvice + 实现接口 ResponseBodyAdvice
🌸🌸🌸完结撒花🌸🌸🌸