Spring Boot工程中@RestControllerAdvice 统一异常处理

Spring Boot工程中@RestControllerAdvice 统一异常处理

    • 1、简介
    • 2、@RestControllerAdvice实战
      • 2.1、定义响应体结构信息
      • 2.2、定义返回值和对应code的信息
      • 2.3、自定义异常
      • 2.4、RestControllerAdvice来捕获全局异常
      • 2.5、测试统一异常捕获功能

1、简介

互联网公司中,后端通常都会拆分成多个独立的微服务,这时候就会涉及每个服务返回给前端的数据格式不统一问题。下面就来实现一个比较常用的数据格式,统一所有服务的返回值格式。
一般响应的数据格式包括如下几个部分:

{
    "code": 200,//响应编码
    "message": "SUCCESS",//响应文本信息
    "data": {//接口返回值
        "name": "zhangsan",
        "age": 16,
        "sex":}
}

对于异常处理情况,如果我们在controller中通过try catch来处理异常的话,Controller层每个接口都有try catch代码块,代码会变的很冗余。下面我们就通过spring boot的注解来省略掉controller中的try-catch 帮助我们来封装异常信息并返回给前端,这样用户也不会得到一些奇奇怪怪的错误提示。

2、@RestControllerAdvice实战

2.1、定义响应体结构信息

@data
@AllArgsConstructor
public class ResponseMessage<T> {
	//响应编码
    private int code;
    //响应文本信息
    private String message;
    //接口返回值
    private T data;
}

2.2、定义返回值和对应code的信息

public enum ResponseStatus{
    SUCCESS(200, "成功"),
    METHODFAIL(500, "ENCOUNTER AN ERROR WHEN EXECUTE METHOD"),
    UNKNOWEXCEPTION(3000, "THIS IS AN UNKNOW EXCEPTION");

    private int code;
    private String message;

    ResponseStatus(int code, String message){
        this.code = code;
        this.message= message;
    }
    public int getCode() {
		return code;
	}

	public String getMessage() {
		return message;
	}
}

2.3、自定义异常

在业务层总会因为某些原因,需要手动抛出异常,响应给前端,提示用户。一般这种异常不建议直接使用RuntimeException,一般会手动创建自己的异常类,并继承RuntimeException。

public class BusinessRuntimeException extends RuntimeException {

    public BusinessRuntimeException (String message){
        super(message);
    }
}

2.4、RestControllerAdvice来捕获全局异常

@RestControllerAdvice都是对Controller进行增强的,可以全局捕获spring mvc抛的异常。
@ExceptionHandler(value = Exception.class)
ExceptionHandler的作用是用来捕获指定的异常。

@RestControllerAdvice(annotations = RestController.class)
public class OverAllExceptionAdvice<T> {

    public ResponseMessage sendSuccessResponse(){
		return new ResponseMessage(ResponseStatus.SUCCESS.getCode(),ResponseStatus.SUCCESS.getMessage(), null);
	}

	public ResponseMessage sendSuccessResponse(T data) {
		return new ResponseMessage(ResponseStatus.SUCCESS.getCode(),ResponseStatus.SUCCESS.getMessage(), data);
	}

	@ExceptionHandler(BusinessRuntimeException.class)
	public ResponseMessage sendErrorResponse_UserDefined(Exception exception){
		return new ResponseMessage(ResponseStatus.METHODFAIL.getCode(),((BusinessRuntimeException )exception).getMessage(), null);
	}

	@ExceptionHandler(Exception.class)
	public ResponseMessage sendErrorResponse_System(Exception exception){
		if (exception instanceof BusinessRuntimeException) {
			return this.sendErrorResponse_UserDefined(exception);
		}

		return new ResponseMessage(ResponseStatus.UNKNOWEXCEPTION.getCode(),ResponseStatus.UNKNOWEXCEPTION.getMessage(), null);
	}
}

通过上面的一波操作,我们的controller中就不需要再去写大量的try-catch了,RestControllerAdvice会自动帮助catch,并匹配相应的ExceptionHandler,然后重新封装异常信息,返回值,统一格式返回给前端。

2.5、测试统一异常捕获功能

@GetMapping("/doObject")
public CallResultMsg testObjectReturn(){
    Map<String, Integer> map = new HashMap();
    map.put("张三", 19);
    map.put("李四", 29);
    map.put("王五", 30);
    return new OverAllExceptionAdvice<Map>().sendSuccessResponse(map);
}


@GetMapping("/doException/{x}")
public int testExceptionResturn(@PathVariable int x){
    if (0 < x && x < 10){
        throw new BusinessRuntimeException (ResponseStatus.METHODFAIL.getMessage());
    } else {
        return  1/0;
    }
}

执行结果:

{
    "code": 200,
    "message": "SUCCESS",
    "data": {
        "张三": 19,
        "李四": 29,
        "王五": 30
    }
}
{
    "code": 500,
    "message": "ENCOUNTER AN ERROR WHEN EXECUTE METHOD ",
    "data": null
}

你可能感兴趣的:(Java面试笔记,spring,java,restful,spring,boot)