目录
-
- <dependency>
- <groupId>org.hibernate.validatorgroupId>
- <artifactId>hibernate-validatorartifactId>
- dependency>
在common目录中新建一个BaseException.class,用于接受全局的异常,一定要附上@RestControllerAdvice,才能被识别。
- /**
- * 全局异常处理器
- */
- @RestControllerAdvice
- public class BaseException {
-
- }
对于参数格式有问题、代码运行错误等不可控因素的系统报错,默认的效果是这样:
而以下是系统异常的封装处理,返回我们规范的报错信息,
@ExceptionHandler是针对不同的报错类
@RequestLogAnnotation是我的aop日志处理,用于保存mysql
- /**
- * 全局异常处理器
- */
- @RestControllerAdvice
- public class BaseException {
-
- /**
- * 系统异常
- * @param e 异常信息
- * @return Result
- */
- @ExceptionHandler(value = {Exception.class})
- @RequestLogAnnotation
- @ResponseBody
- public Result exceptionHandler(Exception e){
-
- return Result.error(500,"系统异常错误,请联系系统管理员处理!");
- }
- }
他的结果就是这样的:
我这里以post接口@RequestBody为例,接口如下,给dto对象前加上@Validated,
- /**
- * 登录
- * @param dto 暂存输入参数dto对象
- * @return
- */
- @RequestLogAnnotation(value = "用户登录")
- @PostMapping("/login")
- public Result login(@RequestBody @Validated LoginDto dto) {
-
- // 进行对比
- Login res = loginService.userLogin(dto);
-
- // 判断结果是否返回该账号信息
- if (res != null) {
- return Result.success(200, "登录成功", data);
- } else {
- return Result.error(501, "登陆失败");
- }
- }
然后,在实体类中给对应参数,加上@NotNull,其中的【(message = "用户账号不能为空")】这一段是在参数未空时报错返回的信息,用于返回给前端,但需要后台处理。
- /**
- * 接受登录请求的参数
- */
- @Data
- public class LoginDto {
-
- @NotNull(message = "用户账号不能为空")
- private String id;
-
- @NotNull(message = "用户密码不能为空")
- private String password;
- }
最后在前面的全局异常类中添加如下代码:
- /**
- * 请求参数缺失异常处理
- * @param ex
- * @return
- */
- @ExceptionHandler(value = {MethodArgumentNotValidException.class})
- @ResponseStatus(HttpStatus.OK)
- @RequestLogAnnotation
- @ResponseBody
- public Result handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
- Result result = new Result();
- BindingResult bindingResult = ex.getBindingResult();
- StringBuilder sb = new StringBuilder("校验失败:");
- for (FieldError fieldError : bindingResult.getFieldErrors()) {
- sb.append(fieldError.getDefaultMessage()).append(", ");
- }
- String msg = sb.toString();
- result.setCode(500);
- result.setMsg(msg);
- return result;
- }
这时候请求里因为参数缺失,就会通过这个方法报错:
新建一个自定义异常类ServiceException.class,继承RuntimeException,如下(这里为了简化,只留一个getter方法和1个构造函数):
- public class ServiceException extends RuntimeException{
- private Integer code;
-
- public Integer getCode() {
- return code;
- }
-
- public ServiceException (Integer code, String msg) {
- super(msg);
- this.code = code;
- }
- }
然后在全局异常类中添加如下代码(和系统异常基本一致,只需要更换@ExceptionHandler中的对应类即可):
- /**
- * 如果抛出的的是ServiceException,则调用该方法
- * @param e 服务异常
- * @return Result
- */
- @ExceptionHandler(ServiceException.class)
- @RequestLogAnnotation
- @ResponseBody
- public Result serviceExceptionHandle(ServiceException e){
-
- return Result.success(e.getCode(), e.getMessage());
- }
这时候就可以在接口中使用try和catch方法进行判断异常使用了,如下:
- // sql执行判断
- try{
- res = getOne(queryWrapper);
- } catch (Exception e) {
- throw new ServiceException(500, e);
- }