如果服务器接口报错,接口返回报错信息,是怎么实现的呢?
接口调用示例
controller代码
@AllArgsConstructor
@RestController
@Slf4j
public class DemoController {
@GetMapping("exceptionTest")
public Result exceptionTest(Integer integer1, Integer integer2) {
Integer result = 0;
try {
result = integer2/integer1;
} catch (Exception e) {
throw new RuntimeException("除数不能为0");
}
return Result.success(result);
}
}
一般情况下这样写,具体报错信息只能在服务器端看到,接口返回的只是服务器报错,具体报什么错,无法获知。要把服务器端的报错信息,返回到前端,进行以下操作:
(1)增加“统一拦截异常类”
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
//统一拦截异常
@RestControllerAdvice(basePackages = "com.example.demo")
public class ExceptionAdvice {
/**
* 顶级异常捕获并统一处理,当其他异常无法处理时候选择使用
*/
@ExceptionHandler({Exception.class})
public Result<?> handle(Exception ex) {
return Result.failed(ex.getMessage());
}
}
注意添加统一异常拦截类之后,会对com.example.demo包下的代码异常进行拦截,handle放屁注解配的是Exception.class,对所有异常进行拦截,如果有自定义类,可以换成自定义类class。拦截后会return Result.failed(ex.getMessage());你会发现,接口返回的是Result.failed(ex.getMessage()),而不是接口的返回值,异常拦截处理方法的返回代替了接口的返回,那么需要定义一个统一的接口返回类Result
(2)增加统一接口返回类
package com.example.demo.common;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result<T> {
private Integer code;
private String message;
private T data;
public static <T> Result<T> success(T data) {
return new Result<>(ResultEnum.SUCCESS.getCode(), ResultEnum.SUCCESS.getMessage(), data);
}
public static <T> Result<T> success(String message, T data) {
return new Result<>(ResultEnum.SUCCESS.getCode(), message, data);
}
public static Result<?> failed() {
return new Result<>(ResultEnum.FAILED.getCode(), ResultEnum.FAILED.getMessage(), null);
}
public static Result<?> failed(String message) {
return new Result<>(ResultEnum.FAILED.getCode(), message, null);
}
public static Result<?> failed(IResult errorResult) {
return new Result<>(errorResult.getCode(), errorResult.getMessage(), null);
}
public static <T> Result<T> instance(Integer code, String message, T data) {
Result<T> result = new Result<>();
result.setCode(code);
result.setMessage(message);
result.setData(data);
return result;
}
}
package com.example.demo.common;
public interface IResult {
Integer getCode();
String getMessage();
}
package com.example.demo.common;
import lombok.Data;
public enum ResultEnum implements IResult{
SUCCESS(200, "接口调用成功"),
FAILED(500, "服务器异常"),
FORBIDDEN(401, "没有权限访问资源");
private Integer code;
private String message;
ResultEnum(int code, String message) {
this.code = code;
this.message = message;
}
@Override
public Integer getCode() {
return this.code;
}
@Override
public String getMessage() {
return this.message;
}
}
这样拦截之后会对异常的状态和提示信息与接口返回的类型一致,前端更容易解析。