springboot全局返回数据封装及其全局异常
1、全局返回数据封装
1、首先先写一个数据返回结构
写一个请求成功返回类,也就是整体返回的数据结构,code、msg、data,然后再写一些列方法,供处理器调用,处理器调用返回的数据类型,就是自己定义的类型
例如:
{
"code": 1,
"msg": "SUCCESS",
"data": {
"hello": "hello"
}
}
自定义返回结构
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PlatformResult implements Serializable {
/**
* 自定义状态码
*/
private Integer code;
/**
* 自定义消息
*/
private String msg;
/**
* 返回数据
*/
private Object data;
private void setPlatformResult(ResultCodeEnum resultCodeEnum){
this.code=resultCodeEnum.getCode();
this.msg=resultCodeEnum.getMsg();
}
public PlatformResult success(){
PlatformResult platformResult=new PlatformResult();
platformResult.setPlatformResult(ResultCodeEnum.SUCCESS);
return platformResult;
}
public static PlatformResult success(Object data){
PlatformResult platformResult=new PlatformResult();
platformResult.setPlatformResult(ResultCodeEnum.SUCCESS);
platformResult.setData(data);
return platformResult;
}
public static PlatformResult failure(ResultCodeEnum resultCodeEnum){
PlatformResult platformResult=new PlatformResult();
platformResult.setPlatformResult(ResultCodeEnum.Fail);
return platformResult;
}
public static PlatformResult failure(ResultCodeEnum resultCodeEnum,Object data){
PlatformResult platformResult=new PlatformResult();
platformResult.setPlatformResult(ResultCodeEnum.Fail);
platformResult.setData(data);
return platformResult;
}
2、封装数据处理器,全局返回数据
@RestControllerAdvice
public class ResponseResultHandler implements ResponseBodyAdvice<Object> {
//判断方法有无返回类型,有则调用 beforeBodyWrite 方法
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
//判断方法的返回值
return !returnType.getMethod().getReturnType().isAssignableFrom(Void.TYPE);
}
@Override
public Object beforeBodyWrite(Object body
, MethodParameter returnType
, MediaType selectedContentType
, Class<? extends HttpMessageConverter<?>> selectedConverterType
, ServerHttpRequest request
, ServerHttpResponse response) {
if (body instanceof ErrorResult){
return ErrorResult.failure((ErrorResult) body);
}else{
return PlatformResult.success(body);
}
}
}
2、全局处理异常
1、写一个异常处理类
自定义异常类返回结构体
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ErrorResult implements Serializable {
private static final long serialVersionUID = 1L;
/**
* HTTP响应状态码 {@link org.springframework.http.HttpStatus}
*/
private Integer status;
/**
* 异常堆栈的精简信息
*
*/
private String message;
/**
* 错误状态码
*/
private Integer code;
/**
* 异常的名字
*/
private String exception;
public static ErrorResult failure(ResultCodeEnum resultCodeEnum,Throwable e, HttpStatus httpStatus) {
ErrorResult errorResult = new ErrorResult();
errorResult.setCode(resultCodeEnum.getCode());
errorResult.setMessage(resultCodeEnum.getMsg());
errorResult.setStatus(httpStatus.value());
errorResult.setException(e.getClass().getName());
return errorResult;
}
public static ErrorResult failure(ErrorResult errorResult) {
ErrorResult result = new ErrorResult();
result.setCode(errorResult.getCode());
result.setMessage(errorResult.getMessage());
result.setStatus(errorResult.getStatus());
return result;
}
public static ErrorResult failure(BusinessException e) {
ErrorResult errorResult = ErrorResult
.failure(e.getResultCodeEnum() == null ? ResultCodeEnum.SYSTEM_INNER_ERROR : e.getResultCodeEnum(),
e, HttpStatus.OK);
errorResult.setMessage(e.getMessage());
return errorResult;
}
}
2、自定义异常类
自定义一个运行期异常,供自己抛出使用
@Data
public class BusinessException extends RuntimeException{
protected String message;
protected Integer code;
protected ResultCodeEnum resultCodeEnum;
public BusinessException() {
}
public BusinessException(String message) {
this();
this.message = message;
}
public BusinessException(ResultCodeEnum resultCodeEnum) {
this.resultCodeEnum = resultCodeEnum;
this.code = resultCodeEnum.getCode();
this.message = resultCodeEnum.getMsg();
}
}
3、全局异常处理
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
/**
* 如果没有使用 @ResponseStatus 来注明状态,需要通过 throw new 来抛出异常
* 处理通用自定义业务异常
*/
//抛出自定义异常时,调用
@ExceptionHandler(BusinessException.class)
public ErrorResult handleBusinessException(BusinessException e, HttpServletRequest request) {
// log.error("handleBusinessException start, uri:{}, exception:{}, caused by: {}"
// , request.getRequestURI()
// , e.getClass()
// , e.getMessage() + e.getData());
return ErrorResult.failure(e);
}
/**
* 处理运行时系统异常(反500错误码)
*/
//500异常时,抛出此异常
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(RuntimeException.class)
public ErrorResult handleRuntimeException(RuntimeException e, HttpServletRequest request) {
log.error("handleRuntimeException start, uri:{}, caused by: ", request.getRequestURI(), e);
return ErrorResult.failure(ResultCodeEnum.SYSTEM_INNER_ERROR, e, HttpStatus.INTERNAL_SERVER_ERROR);
}
}