记一次封装接口返回值问题
Posted _瞳孔
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记一次封装接口返回值问题相关的知识,希望对你有一定的参考价值。
因为之前的封装都是一个Result然后三个成员code、msg和data,所以无论是否返回数据,返回结果都会有data,于是我为了完整,就做了如下修改:
Result.java:
import lombok.Data;
/**
* 统一返回格式
*/
public class Result
/**
* 成功(无返回数据、默认成功信息)
* @return Result<Void>
*/
public static StandardResult<Void> success()
NoDataResult noDataResult = new NoDataResult();
noDataResult.setCode(ResultCode.SUCCESS.getCode());
noDataResult.setMsg(ResultCode.SUCCESS.getMessage());
return noDataResult;
/**
* 成功(无返回数据、自定义成功信息)
* @return Result<Void>
*/
public static StandardResult<Void> success(String message)
NoDataResult noDataResult = new NoDataResult();
noDataResult.setCode(ResultCode.SUCCESS.getCode());
noDataResult.setMsg(message);
return noDataResult;
/**
* 成功(有返回数据,默认成功信息)
* @return Result<V>
*/
public static <V> StandardResult<V> success(V data)
DataResult<V> dataResult = new DataResult<>();
dataResult.code = ResultCode.SUCCESS.getCode();
dataResult.msg = ResultCode.SUCCESS.getMessage();
dataResult.data = data;
return dataResult;
/**
* 成功(有返回数据,自定义成功信息)
* @return Result<V>
*/
public static <V> StandardResult<V> success(String message, V data)
DataResult<V> dataResult = new DataResult<>();
dataResult.code = ResultCode.SUCCESS.getCode();
dataResult.msg = message;
dataResult.data = data;
return dataResult;
/**
* 失败(默认错误信息)
* @return Result<Void>
*/
public static StandardResult<Void> failure()
NoDataResult noDataResult = new NoDataResult();
noDataResult.setCode(ResultCode.FAILURE.getCode());
noDataResult.setMsg(ResultCode.FAILURE.getMessage());
return noDataResult;
/**
* 失败,使用已定义枚举
*/
public static StandardResult<Void> failure(ResultCode resultCode)
NoDataResult noDataResult = new NoDataResult();
noDataResult.setCode(resultCode.getCode());
noDataResult.setMsg(resultCode.getMessage());
return noDataResult;
/**
* 失败,使用自定义错误信息
*/
public static StandardResult<Void> failure(String message)
NoDataResult noDataResult = new NoDataResult();
noDataResult.setCode(ResultCode.FAILURE.getCode());
noDataResult.setMsg(message);
return noDataResult;
/**
* 失败,使用自定义错误码和错误信息
*/
public static StandardResult<Void> failure(Integer code, String message)
NoDataResult noDataResult = new NoDataResult();
noDataResult.setCode(code);
noDataResult.setMsg(message);
return noDataResult;
/**
* 无数据返回模板
*/
@Data
static class NoDataResult implements StandardResult<Void>
private Integer code;
private String msg;
@Override
public Void getData()
return null;
/**
* 有数据返回模板
*/
@Data
static class DataResult<V> implements StandardResult<V>
private Integer code;
private String msg;
private V data;
ResultCode.java:
/**
* 状态码类
*/
@Getter
@AllArgsConstructor
public enum ResultCode
// 默认成功提示
SUCCESS(200, "success"),
// 默认失败提示
FAILURE(400, "fail"),
/*
* 非运行时异常(1000 - 1999)
*/
PROGRAM_INSIDE_EXCEPTION(1000, "程序内部异常"),
/*
* 运行时异常——操作异常(2000 - 5999)
*/
ILLEGAL_REQUEST_PARAMETER(2000, "非法请求参数"),
/*
* 运行时异常——风险异常(6000 - 9999)
*/
ILLEGAL_REQUEST_ROUTE(6000, "非法路由请求");
private final Integer code;
private final String message;
因为是code、msg和data都变成了内部类的成员属性,所以类型都是Result.NoDataResult
,Result.DataResult
之类的,我感觉很难看,于是我让两个内部类都实现一个接口,用以统一返回类型:
StandardResult.java:
public interface StandardResult<T>
Integer getCode();
String getMsg();
T getData();
这么封装貌似是没有问题的,测试也没有问题:
但由于我这个是微服务项目,在使用feign进行服务调用的时候,就开始报错了:
这个(no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
,我经过查阅资料发现,是因为feign做调用的说话返回值类型不能被反序列化,而我为了类型统一,就实现了StandardResult接口,因此无法被序列化,我也想不出来怎么既可以统一返回类型又可以被序列化,于是只能在feign api内使用内部类类型:
其余地方都使用StandardResult:
注意,如果要使用内部类进行类型约束,需要将Result类中的内部类访问权限改为public:
当然如果不是微服务项目的话,可以直接使用我上面发的封装,如果是微服务项目就得注意我说的那几个修改点
如果有兴趣了解更多相关内容,欢迎来我的个人网站看看:瞳孔的个人网站
以上是关于记一次封装接口返回值问题的主要内容,如果未能解决你的问题,请参考以下文章