如果服务器接口报错,接口返回报错信息,是怎么实现的呢?
接口调用示例
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;}@Overridepublic Integer getCode() {return this.code;}@Overridepublic String getMessage() {return this.message;}}
这样拦截之后会对异常的状态和提示信息与接口返回的类型一致,前端更容易解析。