Springcloud学习笔记58--SpringBoot拦截全局异常统一处理(RestControllerAdvice注解)
1. 应用场景
如果和前端约定好使用固定的自定义格式返回参数,如下:
{ "code": 200, "msg": "操作成功", "data": { "equipment": 55, "code": 99, "point": 2 } }
但在运行时发现了异常,默认的异常返回格式如下:
{ "timestamp": "2019-09-16T08:22:58.463+0000", "status": 500, "error": "Internal Server Error", "message": "条码已存在!", "path": "/machine/molding" }
我们希望以自定义的格式返回所有数据,那么就需要将异常进行拦截处理并统一返回。
1.1 @RestControllerAdvice 介绍
@RestControllerAdvice是一个组合注解,由@ControllerAdvice、@ResponseBody组成,而@ControllerAdvice继承了@Component,因此@RestControllerAdvice本质上是个Component,用于定义@ExceptionHandler,@InitBinder和@ModelAttribute方法,适用于所有使用@RequestMapping方法。
@RestControllerAdvice的特点
- 通过@ControllerAdvice注解可以将对于控制器的全局配置放在同一个位置。
- 注解了@RestControllerAdvice的类的方法可以使用@ExceptionHandler、@InitBinder、@ModelAttribute注解到方法上。
- @RestControllerAdvice注解将作用在所有注解了@RequestMapping的控制器的方法上。
- @ExceptionHandler:用于指定异常处理方法。当与@RestControllerAdvice配合使用时,用于全局处理控制器里的异常。
- @InitBinder:用来设置WebDataBinder,用于自动绑定前台请求参数到Model中。
- @ModelAttribute:本来作用是绑定键值对到Model中,当与@ControllerAdvice配合使用时,可以让全局的@RequestMapping都能获得在此处设置的键值对
2.自定义返回实体类
package com.ttbank.flep.pojo; import lombok.*; import java.io.Serializable; /** * @Author lucky * @Date 2023/12/7 10:16 */ @Data @Builder @ToString @NoArgsConstructor @AllArgsConstructor public class Result<T> implements Serializable { public static final String SUCCESS_CODE="00000000"; public static final String SUCCESS_MSG="SUCCESS"; private String code; private String msg; private T data; public static <T> Result success(){ return new Result(SUCCESS_CODE,SUCCESS_MSG,null); } public static <T> Result success(T data){ return new Result(SUCCESS_CODE,SUCCESS_MSG,data); } public static <T> Result error(String code,String msg){ return new Result(code,msg,null); } public static <T> Result error(String code,String msg,T data){ return new Result(code,msg,data); } }
3 自定义异常枚举类
package com.ttbank.flep.exception; /** * @Author lucky * @Date 2023/12/7 9:45 */ public enum FlepExpEnum { PARAM_CHECK_ERROR("flep1001","参数校验失败"), SUBSYS_INFO_ERROR("flep1002","子系统不存在或未启用"), SUBSYS_CONTENT_ERROR("flep1002","子系统内容关联不存在或未启用"); private final String code; private final String message; FlepExpEnum(String code, String message) { this.code = code; this.message = message; } public String getCode() { return code; } public String getMessage() { return message; } }
4 自定义异常信息类
package com.ttbank.flep.exception; import lombok.Data; import lombok.NoArgsConstructor; /** * @Author lucky * @Date 2022/7/11 17:15 */ @Data @NoArgsConstructor public class FlepException extends RuntimeException { private String code; private String message; private String data; public FlepException(FlepExpEnum flepExpEnum){ this.code=flepExpEnum.getCode(); this.message=flepExpEnum.getMessage(); } public FlepException(FlepExpEnum flepExpEnum,String data){ this.code=flepExpEnum.getCode(); this.message=flepExpEnum.getMessage(); this.data=data; } public FlepException(String code,String message,String data){ this.code=code; this.message=message; this.data=data; } }
5. 定义异常统一处理类
package com.ttbank.flep.exception; import com.ttbank.flep.pojo.Result; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; /** * @Author lucky * @Date 2023/12/7 10:06 */ @Slf4j @RestControllerAdvice public class FlepExceptionHandler { @ExceptionHandler(Exception.class) public Result flepExceptionHandler(Exception exception){ if(exception instanceof FlepException){ FlepException flepException= (FlepException) exception; return Result.error(flepException.getCode(),flepException.getMessage(),flepException.getData()); }else{ log.error("发生了系统异常:",exception); return Result.error("999","系统异常"); } } }
6. 测试类
package com.ttbank.flep.controller; import com.ttbank.flep.aspect.MyAnnotation; import com.ttbank.flep.exception.FlepExpEnum; import com.ttbank.flep.pojo.Result; import com.ttbank.flep.util.HttpUtil; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import java.util.HashMap; import java.util.Map; /** * @Author lucky * @Date 2023/12/7 10:55 */ @RestController //@RequestMapping("/test") public class ExceptionTestController { @PostMapping("/getFlepInfo") public Result<String> getFlepInfo(@RequestParam String busiType){ if(busiType.equals("1")){ return Result.success("111"); }else if(busiType.equals("2")){ return Result.error(FlepExpEnum.SUBSYS_INFO_ERROR.getCode(),FlepExpEnum.SUBSYS_INFO_ERROR.getMessage() ); }else if(busiType.equals("3")){ return Result.error(FlepExpEnum.SUBSYS_CONTENT_ERROR.getCode(),FlepExpEnum.SUBSYS_CONTENT_ERROR.getMessage() ); }else { throw new RuntimeException(); } } }
postman测试结果:
参考文献:
https://blog.csdn.net/WZH577/article/details/100921971
https://blog.csdn.net/m0_51620667/article/details/127013347