先介绍一下业务场景,如今有一个业务对象基类:
public class JsonRequest{
private String msg;
private String code;
}
如今有N多子类对其进行继承,而且自带一个业务对象
public class DetailJsonRequest extends JsonRequest{
private T body;
}
想这样的一个对象,可能被用于序列号传输对象,在微服务中可能被用到
那么如今,我做为业务受理方,须要接受消费方发送来的请求,通常经过验签解密以后,会获取到一个字符串,咱们这里假设序列化方式为Json
那么解析之后,我获取到这么一个字符串:
String content = "{\"body\":{\"id\":\"1123\",\"name\":\"macky\"},\"code\":\"1\",\"msg\":\"成功\"}";
接下来,根据我须要的业务类型,进行转换:
DetailJsonRequest jsonObject = JSON.parseObject(content, DetailJsonRequest.class);
DetailJsonRequest jsonObject = JSON.parseObject(content, new TypeReference<DetailJsonRequest<JsonContent>>(JsonContent.class) {});
接下来,让咱们看看效果:
DetailJsonRequest(body={"name":"macky","id":"1123"})
DetailJsonRequest(body=JsonContent(id=1123, name=macky))
发现了啥猫腻了吗,这里丢失了msg和code信息,大惊失色!!
通过各类查找,经过文档、github issue等等等,发现了罪魁祸首——toString方法
我在日常工做中,会使用到lombok插件,而后会数据打上@data注解,轻松完成一个bean构造
因此上述的JsonRequest和DetailJsonRequest都挂着@data注解
如今,给DetailJsonRequest加上另外一个注解:@ToString(callSuper=true)
或者是若是你没有使用lombok,那么使用这样一个toString方法:
@Override
public String toString() {
return "DetailJsonRequest{" +
"body=" + body +
", msg='" + super.getMsg() + '\'' +
", code='" + super.getCode() + '\'' +
'}';
}
从新验证,会发现俩个方式的解析均可以获得msg和code信息:
DetailJsonRequest(super=JsonRequest(msg=成功, code=1), body={"name":"macky","id":"1123"})
DetailJsonRequest(super=JsonRequest(msg=成功, code=1), body=JsonContent(id=1123, name=macky))
问题解决了,那么如今回过头来看看,为什么这样作是能够的,知其然,知其因此然
……未完待续
如如有错,烦请指出