Spring Boot RestControllerAdvice的用法

Posted 大树叶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Boot RestControllerAdvice的用法相关的知识,希望对你有一定的参考价值。

在Spring Boot中,应该用RestControllerAdvice 来统一异常处理

在做前后端分离的项目时,后端通常都会拆分成多个独立的微服务,这时候就会涉及每个服务返回给前端的数据格式问题了。下面就来实现一个比较常用的数据格式,统一所有服务的返回值格式。
一般返回的数据格式会包括4个部分,第一部分: 请求处理是否成功,第二部分:服务处理结果编码,第三部分:编码对应的文本信息,第四部分:返回值。如下所示:


“result”: true,
“code”: 1000,
“message”: “SUCCESS”,
“data”:
“lantian”: 17,
“qingfen”: 16,
“baiyun”: 18


对于异常处理情况,我们也需要统一成上面的格式。如果我们在controller中通过try catch来处理异常的话,会出现一个问题就是每个函数里都加一个Try catch,代码会变的很乱。下面我们就通过spring boot的注解来省略掉controller中的try-catch 帮助我们来封装异常信息并返回给前端,这样用户也不会得到一些奇奇怪怪的错误提示。


“result”: false,
“code”: 3000,
“message”: “THIS IS AN UNKNOW EXCEPTION”,
“data”: null

1:定义返回值结构信息(get, set函数省略)
public class CallResultMsg
private boolean result;
private int code;
private String message;
private T data;

2:定义返回值和对应code的信息(get, set函数省略)
public enum CodeAndMsg
SUCCESS(1000, “SUCCESS”),
METHODFAIL(2000, “ENCOUNTER AN ERROR WHEN EXECUTE METHOD”),
UNKNOWEXCEPTION(3000, “THIS IS AN UNKNOW EXCEPTION”);

private int code;
private String msg;

CodeAndMsg(int code, String msg)
    this.code = code;
    this.msg = msg;


3:自定义异常
对于一些特别的异常,我们可以自定义Exception和Error Code,这里自定义一个异常(需要继承RuntimeException)

public class UserDefinedException extends RuntimeException
private CodeAndMsg exception;

public UserDefinedException(CodeAndMsg exception)
    this.exception = exception;


public CodeAndMsg getException() 
    return exception;


public void setException(CodeAndMsg exception) 
    this.exception = exception;


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

@RestControllerAdvice(annotations = RestController.class)
public class UniformReponseHandler

@ResponseStatus(HttpStatus.OK)
public CallResultMsg sendSuccessResponse()
    return new CallResultMsg(true, CodeAndMsg.SUCCESS, null);


@ResponseStatus(HttpStatus.OK)
public CallResultMsg sendSuccessResponse(T data) 
    return new CallResultMsg(true, CodeAndMsg.SUCCESS, data);


@ExceptionHandler(UserDefinedException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public CallResultMsg sendErrorResponse_UserDefined(Exception exception)
    return new CallResultMsg(false, ((UserDefinedException)exception).getException(), null);


@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public CallResultMsg sendErrorResponse_System(Exception exception)
    if (exception instanceof UserDefinedException) 
        return this.sendErrorResponse_UserDefined(exception);
    

    return new CallResultMsg(false, CodeAndMsg.UNKNOWEXCEPTION, null);


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

5:ControllerAdvice 和 RestControllerAdvice的区别
@ControllerAdvice 和 @RestControllerAdvice都是对Controller进行增强的,可以全局捕获spring mvc抛的异常。
RestControllerAdvice = ControllerAdvice + ResponseBody
6:测试统一异常捕获功能

@GetMapping("/doTestObject")
public CallResultMsg testObjectReturn()
Map<String, Integer> map = new HashMap();
map.put(“qingfen”, 16);
map.put(“lantian”, 17);
map.put(“baiyun”, 18);
return new UniformReponseHandler().sendSuccessResponse(map);

@GetMapping("/doTestException/x")
public int testExceptionResturn(@PathVariable int x)
if (0 < x && x < 10)
throw new UserDefinedException(CodeAndMsg.METHODFAIL);
else
return 1/0;


返回结果:


“result”: true,
“code”: 1000,
“message”: “SUCCESS”,
“data”:
“lantian”: 17,
“qingfen”: 16,
“baiyun”: 18



“result”: false,
“code”: 2000,
“message”: "ENCOUNTER AN ERROR WHEN EXECUTE METHOD ",
“data”: null

以上是关于Spring Boot RestControllerAdvice的用法的主要内容,如果未能解决你的问题,请参考以下文章

Spring-Boot:同时处理多个请求

spring Restcontroller 或 RepositoryRestResource 用啥

Spring:RestController 和 Controller 的不同异常处理程序

Spring Boot 学习例子

Spring Boot 2Spring Boot CLI

为啥 Spring Boot 应用程序 pom 同时需要 spring-boot-starter-parent 和 spring-boot-starter-web?