当前位置: 首页 > article >正文

java属性不被json化_fastJson 格式化继承自ArrayList 的类时属性是不会json化的

在项目中遇到了一个JSON的坑。记录下。

直接上代码:

import java.util.ArrayList;

import com.alibaba.fastjson.JSON;

public class MyList extends ArrayList {

private int size;

private String specialName;

public MyList(){

super(0);

}

public MyList(int size){

super(0);

this.size = size;

}

public MyList(String specialName){

super(0);

this.specialName = specialName;

}

public MyList(int size, String specialName){

super(0);

this.size = size;

this.specialName = specialName;

}

public int getSize() {

return size;

}

public void setSize(int size) {

this.size = size;

}

public String getSpecialName() {

return specialName;

}

public void setSpecialName(String specialName) {

this.specialName = specialName;

}

public static void main(String[] args){

MyList list = new MyList();

list.add(1);

list.add(2);

list.add(3);

list.add(4);

list.setSpecialName("just a test");

list.setSize(4);

System.out.println(JSON.toJSON(list));

System.out.println(JSON.toJSONString(list));

}

}

输出的结果为:

[1,2,3,4]

[1,2,3,4]

但是我们期望的结果却是类似于下面这样的结果:

{size:4, specialName:"just a test", [1,2,3,4]}

那么是哪里出问题了呢?导致 MyList的 size 属性和 specialName 在JSON格式化时,被丢弃了呢?

下面在看一个例子:

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import com.alibaba.fastjson.JSON;

public class MyList2 {

private int size;

private String specialName;

private List list;

public MyList2(){

}

public int getSize() {

return size;

}

public void setSize(int size) {

this.size = size;

}

public String getSpecialName() {

return specialName;

}

public void setSpecialName(String specialName) {

this.specialName = specialName;

}

public List getList() {

return list;

}

public void setList(List list) {

this.list = list;

}

public static void main(String[] args){

MyList2 myList = new MyList2();

ArrayList list = new ArrayList<>();

list.add(1);

list.add(2);

list.add(3);

list.add(4);

myList.setSpecialName("just a test");

myList.setSize(4);

myList.setList(list);

System.out.println(JSON.toJSON(myList));

System.out.println(JSON.toJSONString(myList));

System.out.println("----------------");

Map map = new HashMap<>();

map.put("size", 4);

map.put("specialName", "just a test");

map.put("list", list);

map.put("myList", myList);

System.out.println(JSON.toJSON(map));

}

}

输出的结果为:

{"list":[1,2,3,4],"size":4,"specialName":"just a test"}

{"list":[1,2,3,4],"size":4,"specialName":"just a test"}

----------------

{"specialName":"just a test","size":4,"list":[1,2,3,4],"myList":{"list":[1,2,3,4],"size":4,"spe...

结果完全正确。

到这里,我们应该可以知道什么原因了。

上面第一段代码我们期望的结果:

{size:4, specialName:"just a test", [1,2,3,4]}

但是想一想,这个格式有什么问题吗?仔细想一想。

FK,这个格式是完全错误的!他是不合法的。试想一下,JSON格式说白了,它是 Javascript 的一个子集,合法的json对象它是 javascript 中的对象,但是:

{size:4, specialName:"just a test", [1,2,3,4]}

他是一个合法的javascript对象吗????

显然,它不是的。因为其中的 [1,2,3,4] ,我们无法访问,它没有对应到一个属性。所以我们无法访问它。所以他不是一个合法的javascript对象,显然也就更加不是一个合法的json对象了。所以第一个例子,输出的结果:[1,2,3,4] 其实是可以接受的。

是我们自己想要将一个不适合转化成JSON格式的Java对象强制转化成一个json格式,所以也就难免出现意料之外的情况了。那么 [1,2,3,4] 这个结果是如何来的呢。经过调试,其中的原因是,因为MyList继承自ArrayList,所以在JSON格式化时,就是将其作为了一个List或者说数组来处理的,我们看下相关源码:

public static final Object toJSON(Object javaObject) {

return toJSON(javaObject, ParserConfig.getGlobalInstance());

}

@SuppressWarnings("unchecked")

public static final Object toJSON(Object javaObject, ParserConfig mapping) {

if (javaObject == null) {

return null;

}

if (javaObject instanceof JSON) {

return (JSON) javaObject;

}

if (javaObject instanceof Map) {

Map map = (Map) javaObject;

JSONObject json = new JSONObject(map.size());

for (Map.Entry entry : map.entrySet()) {

Object key = entry.getKey();

String jsonKey = TypeUtils.castToString(key);

Object jsonValue = toJSON(entry.getValue());

json.put(jsonKey, jsonValue);

}

return json;

}

if (javaObject instanceof Collection) {

Collection collection = (Collection) javaObject;

JSONArray array = new JSONArray(collection.size());

for (Object item : collection) {

Object jsonValue = toJSON(item);

array.add(jsonValue);

}

return array;

}

我们的MyList的对象,在 if (javaObject instanceof Collection) 处为true,所以被当做了JSONArray 来处理的,每次处理JSONArray 中的一项,所以显然就不会处理到 size属性和specialName属性了,所以这两个属性被抛弃了。这是 JSON.toJSON() 的处理过程。

下面看下 JSON.toJSONString(),其实也是一样,当成了数组或者说List来处理了:

上面的代码 else if (List.class.isAssignableFrom(clazz)) 处为 true,所以其实是使用了 ListSerializer.instance 来处理了 MyList 的对象的,也就是当做了java.util.List 来处理的,所以自然就抛弃了 size属性和specialName属性。和上面的原理是一样的。

总结下:

1)MyList这样继承自List的对象,并且有扩展属性的,它在json格式中是不能十分恰当的表示的,它会被当成List来处理,从而抛弃其它非List的属性。

2)避免方法就是使用组合代替继承,或者使用Map,java.util.Map 天生就和json格式是最合适的,其实javascript中的对象,其实在某种程度上就是一个Map而已,属性名就是map中的key, 属性的值就是map的value。

3)JSON格式介绍参见:http://www.cnblogs.com/digdeep/p/4572662.html

转载自:http://www.bkjia.com/Javabc/1020836.html

http://www.lryc.cn/news/2420566.html

相关文章:

  • Android 14.0 进入recovery模式(等待用户选择recovery模式界面)进入自动恢复出厂设置模式
  • Autodesk MAYA 2013 SP1 for Win/Mac OSX 【简体中文版】
  • Ubuntu 安装实录
  • SQL语法大全[转]
  • 经典秒杀问题
  • AT89S51/52单片机详细英文缩写解释汇总
  • 几个非常简单漂亮的手机版网页_有了这几个网站,我的工作效率提高了不止3倍!...
  • macOS 内核之 OS X 系统的起源
  • Firefox 9发布 可提升JavaScript性能锋利了html5
  • 10个jQuery技术博客[XiaoFeng收藏]
  • 僵尸国度.Z.Nation
  • 外贸干货|最完整的外贸出口流程,收藏起来耐心看完!
  • Android 实现Button的5种方法
  • 设计模式的艺术之道--组合模式
  • 实现窗体的展开与收起特效(Java)
  • VC++中使用_RecordSetPtr总结
  • MATLAB图像处理的开运算和噪声相关的基本操作-填充和去除—imfill与bwareaopen函数运算
  • js案例---相册选择功能
  • 高质量C\C++编程
  • 运维 常见故障排查
  • SAN (CVPR 2019) :基于二阶通道注意力机制的单图像超分网络
  • 超级实用!Android Studio的10大神器插件,让你的开发效率翻倍!
  • apple tv 开发_如何越狱您的第二代Apple TV以获得更多功能
  • 【linux】计算机内部体系结构
  • uu云验证码识别平台,验证码,验证码识别,全自动验证码识别技术,优优云全自动打码,代答题系统,优优云远程打码平台,uu云打码...
  • 无线路由器桥接完整教程(不会断网)【图文详解】
  • 手机视频产品功能分析
  • 刺客信条3一直显示育碧服务器,刺客信条3免Uplay启动游戏的方法
  • 在电脑上优雅地使用 Flash Player
  • 公告板特效代码收集及实现