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

 

 

posted @ 2023-12-07 16:49  雨后观山色  阅读(523)  评论(0编辑  收藏  举报