统一异常处理和统一返回格式RestControllerAd

闲来无事,自己的模块写完了,就看了看项目框架。之前有个大佬说很多公司都没做统一异常处理和统一返回处理,我现在公司做了,所以就看看。
首先,咱们了解一下什么是统一返回,统一返回就是一种规范,咱们自定义这种规范,从后端返回的数据都按这种规范来,这样前端更容易处理。一般都是用类,这种类都命名为Result

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
csharp复制代码	//主要属性:
@ApiModelProperty(notes = "状态")
private int code;
@ApiModelProperty(notes = "提示信息")
private String message;
@ApiModelProperty(notes = "返回内容")
private T data;

//然后自己定义一些构造方法如下:
public Result() {
this(SUCCESS, "success!");
}

public Result(int code, String message, T content) {
this.code = code;
this.message = message;
this.data = content;
}

public Result(int code, String message) {
this(code, message, null);
}

public static <T> Result<T> error() {
return error(ERROR, "error!");
}

public static <T> Result<T> error(String msg) {
return error(ERROR, msg);
}

public static <T> Result<T> error(int code, String msg) {
return new Result<>(code, msg);
}

public static <T> Result<T> error(String msg, T content) {
return new Result<>(ERROR, msg, content);
}

public static <T> Result<T> error(int code, String msg, T content) {
return new Result<>(code, msg, content);
}

public static <T> Result<T> ok() {
return new Result<>();
}

public static <T> Result<T> ok(String message) {
return new Result<>(SUCCESS, message);
}

public static <T> Result<T> ok(T content) {
return new Result<>(SUCCESS, "success!", content);
}

public static <T> Result<T> ok(int status, T content) {
return new Result<>(status, "success!", content);
}

public static <T> Result<T> ok(int status, String message, T content) {
return new Result<>(status, message, content);
}

@Override
public boolean matching() {
return this.code == 0;
}

定义好返回的类后,就可以开始编写统一返回处理了,在编写统一返回处理之前我们得了解一个接口类ResponseBodyAdvice,这个接口类如其名,主要是对ResponseBody的一个处理,也是就controller的响应进行一个处理。
它有两个方法,第一个方法,这里有两个参数,大家可以自行去了解一下哈,我只用到了returnType.getGenericParameterType(),这个方法是得到返回的数据类型,因此我们就可以判断返回的类型是不是我们规定的了。

1
arduino复制代码 boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType);

这个方法主要是判断需要不需要第二个方法beforeBodyWrite。

如果supports返回的true,就会执行第二个方法,如果返回false就不会执行第二个方法。所以第一个supports,能在定位到包的基础上更精确的处理一些返回值。

至于对返回值的统一处理就靠我们第二方法了。
方法中的body就是相应的返回值了,而returnType.getGenericParameterType()可以获取返回值的类型

1
vbscript复制代码  T beforeBodyWrite(T body, MethodParameter returnType, MediaType selectedContentType,Class<? extends HttpMessageConverter<?>> selectedConverterType,ServerHttpRequest request, ServerHttpResponse response);

我们实现这个接口类,重写这两个方法,并且类上打上注解@RestControllerAdvice(basePackages = “XXX”)
这个注解是拦截controller的,输入包路径后,就是指定的包路径了。
第一个方法,我们实现主要是判断返回类型是不是我们的规范类型,如果不是就返回true,就会执行第二个方法。
第二个方法就可以对数据进行一个处理了,我们就进行一个封装,这样返回类型就是统一规范了。如下:

1
2
3
4
5
6
7
8
9
10
kotlin复制代码   if (body == null) {
return Result.ok();
}
if (body instanceof Result) {
return body;
}
if (returnType.getGenericParameterType().equals(String.class)) {
return body;
}
return Result.ok(body);

完成上述步骤后,即使返回的为空,只要没报错都会有个状态码,和状态,以上就是返回统一格式。

接下来是统一异常处理,统一异常处理,也要用到@RestControllerAdvice注解,拦截所有controller,还有 @ExceptionHandler(),参数是指定异常类型,主要是用这两个注解。代码如下:

1
2
3
4
less复制代码    public ResponseEntity<Object> customExceptionHandler(BaseCustomException exception) {
log.error(exception.getLogMessage());
return new ResponseEntity<>(Result.error(exception.getErrorCode(), exception.getMessage()), exception.getHttpStatus());
}
1
复制代码完成上述代码,这样遇到异常就能按我们的格式抛来了。自定义一个异常,这样就完成自定义异常处理了。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%