R的核心代码:
public class R<T> extends HashMap<String, Object> {
private static final long serialVersionUID = 1L;
@Setter
@Getter
T data;
public R() {
put("code", 0);
put("msg", "success");
}
}
注意:如果调试的时候不会直接显示这个data的值
这是因为idea在调试的时候,在这里显示的数据是通过调用对象的toString方法实现的,而R继承了HashMap,hashmap重写的toString方法只会显示map里面的内容,不会显示data的数据,但是这并不代表data没有值
我们打印出来的值也没有data这个属性,因为sout打印对象时,也是调用的对象的toString方法,但是我们却可以通过getData拿到这个data的值,所以其实data的值在这里面,只是没有打印出来,并且解析成JSON字符串后,这个值也没有出现,因而我们在使用Spring返回这个对象作为返回值时,拿不到这个data,从而会造成错误,我们深入源码,分析一下原因
我们进入toJSONString的源码
我们可以看到,我们返回的json字符串来此writer,所以我们着重关注对writer进行的一些操作
首先会根据这个对象的类型,拿到对应的JSON转换器,Map类型有Map类型的转换器,普通对象有普通对象的转换器,而因为R继承了HashMap,是map型的变量,所以会得到一个用于转换map的转换器,这也就是问题的所在
Class<?> valueClass = object.getClass();
ObjectWriter objectWriter = context.getObjectWriter(valueClass, valueClass);
我们继续往下看,进入这个write方法
来到这个方法后,我们就可以看到data丢失的原因,在将对象转换为JSON字符串前,会将这个对象强制转换为Map类型的变量,然后后面遍历这个map,对递归地往writer里面写入数据,来实现json格式的字符串的转换,而由于此时的R已经被强制转换为了Map类型的变量,因而JSON在处理的时候看不到data这个数据,只是将其当成一个普通的map来处理,所以转换为JSON的时候,data数据会丢失