前言
項目中一般都會有規(guī)定好的接口返回格式,無論成功與失敗,一般格式都是不變的,這樣是為了方便前后端統(tǒng)一處理,今天就來說下前后端統(tǒng)一處理的較為優(yōu)雅的方式;
一、統(tǒng)一的返回格式
一般而言都會有一個統(tǒng)一的返回類作為接口的返回數(shù)據(jù)的封裝,例如:
@Data
public class Result<T> implements Serializable {
private int code = HttpStatus.OK.value();
private String msg;
private T data;
public static <T> Result<T> success() {
return success(null);
}
public static <T> Result<T> failure() {
return failure(HttpStatus.BAD_REQUEST.value(),HttpStatus.BAD_REQUEST.getReasonPhrase());
}
public static <T> Result<T> success(T data) {
return new Result<T>(HttpStatus.OK.value(), HttpStatus.OK.getReasonPhrase(), data);
}
public static <T> Result<T> failure(int errorCode, String errorMsg) {
return failure(errorCode, errorMsg, null);
}
public static <T> Result<T> failure(int code, String errorMsg, T data) {
return new Result<T>(code, errorMsg, data);
}
public Result(int code, String msg, T data) {
this.code = code;
this.msg = msg;
this.data = data;
}
}
然后我們通過此類作為返回參數(shù)的統(tǒng)一封裝,這樣無論成功與否,都是三個參數(shù)
code msg data
二、全局異常處理
- 項目中難免會有異常拋出
- 服務端報錯的異常
- 處理邏輯中的異常(參數(shù)校驗, 邏輯不通等)
- 由于我們一般都是前后端分離項目,所以都是接口方式的返回,那么我們只需要處理接口就可以了
@RestControllerAdvice
@Slf4j
public class ControllerExceptionHandel {
@ExceptionHandler(ValidationException.class)
public Result<String> handleException(ValidationException e) {
e.printStackTrace();
log.error("參數(shù)校驗發(fā)生異常:{}", e.getMessage());
return Result.failure(HttpStatus.BAD_REQUEST.value(), e.getMessage());
}
@ExceptionHandler(value = NullPointerException.class)
public Result<String> exceptionHandler(NullPointerException e) {
e.printStackTrace();
log.error("空指針異常:{}", e.getMessage());
return Result.failure(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage());
}
@ExceptionHandler(value = {Exception.class, RuntimeException.class})
public Result<String> exceptionHandler(Exception e) {
e.printStackTrace();
log.error("運行時發(fā)生異常:{}", e.getMessage());
return Result.failure(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage());
}
@ExceptionHandler(AsyncRequestTimeoutException.class)
public Result<String> handException(AsyncRequestTimeoutException e) {
e.printStackTrace();
log.error("運行時超時異常:{}", e.getMessage());
return Result.failure(HttpStatus.BAD_REQUEST.value(), e.getMessage());
}
}
一般來說控制器可以這樣用
@RestController
@RequestMapping("lang")
public class LangController {
@RequestMapping("get")
public Result get(){
return Result.success(LocalUtil.get("demo"));
}
}
三、全局返回處理(裝逼用的)
還是上面的全局異常處理,不過要增加點東西
- 實現(xiàn)ResponseBodyAdvice接口
- 實現(xiàn)兩個方法
完整代碼如下:
@RestControllerAdvice
@Slf4j
public class ControllerExceptionHandel implements ResponseBodyAdvice<Object>{
@Autowired
private ObjectMapper objectMapper;
@ExceptionHandler(ValidationException.class)
public Result<String> handleException(ValidationException e) {
e.printStackTrace();
log.error("參數(shù)校驗發(fā)生異常:{}", e.getMessage());
return Result.failure(HttpStatus.BAD_REQUEST.value(), e.getMessage());
}
@ExceptionHandler(value = NullPointerException.class)
public Result<String> exceptionHandler(NullPointerException e) {
e.printStackTrace();
log.error("空指針異常:{}", e.getMessage());
return Result.failure(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage());
}
@ExceptionHandler(value = {Exception.class, RuntimeException.class})
public Result<String> exceptionHandler(Exception e) {
e.printStackTrace();
log.error("運行時發(fā)生異常:{}", e.getMessage());
return Result.failure(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage());
}
@ExceptionHandler(AsyncRequestTimeoutException.class)
public Result<String> handException(AsyncRequestTimeoutException e) {
e.printStackTrace();
log.error("運行時超時異常:{}", e.getMessage());
return Result.failure(HttpStatus.BAD_REQUEST.value(), e.getMessage());
}
@Override
public boolean supports(MethodParameter returnType, Class converterType) {
return true;
}
@SneakyThrows
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
Class<?> returnClass = returnType.getMethod().getReturnType();
if (body instanceof String || Objects.equals(returnClass, String.class)) {
return objectMapper.writeValueAsString(Result.success(body));
}
if (body instanceof Result) {
return body;
}
return Result.success(body);
}
}
這樣控制器中既可以像之前那樣使用,還可以像如下使用
它會自動封裝返回結果,無需手動封裝文章來源:http://www.zghlxwxcb.cn/news/detail-638686.html
@RestController
@RequestMapping("lang")
public class LangController {
@RequestMapping("get")
public String get(){
return LocalUtil.get("demo");
}
}
總結
如果項目中按照這種方式 @RestControllerAdvice + ResponseBodyAdvice接口,就能實現(xiàn)大部分的統(tǒng)一返回出參功能了,無論是正常請求還是異常請求,無論是簡單類型還是集合返回,相當于都有了統(tǒng)一的封裝處理;
快試試,用到項目中吧~文章來源地址http://www.zghlxwxcb.cn/news/detail-638686.html
到了這里,關于springboot全局統(tǒng)一返回處理的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!