Gson序列化JSONObject出现多余字段与键序混乱问题咨询
问题根源说明
- 多余字段问题:你混用了
org.json和Gson两个JSON库的API。org.json的JSONObject、JSONArray本身是封装类,内部用map、myArrayList这类私有成员存储数据,直接用Gson序列化该类的实例时,会把内部存储结构的字段也序列化输出,就出现了多余的字段。 - 键顺序错乱问题:原生
org.json的JSONObject内部默认用HashMap存储键值对,HashMap本身不保留插入顺序,所以调用toString()输出的键顺序会和插入顺序不一致。 - 原有代码额外问题:复用同一个
LinkedHashMap实例插入数组,会导致数组内两个手机号对象的内容都被最后一次赋值覆盖,需要每次新建map实例存储不同的手机号数据。
最优解决方案:统一使用Gson完成序列化,保留插入顺序
完全不需要引入org.json的类,直接用Gson配合插入有序的LinkedHashMap构造数据即可,示例代码如下:
import com.google.gson.Gson; import java.util.LinkedHashMap; import java.util.ArrayList; import java.util.List; import java.util.Map; public class JsonTest { public static void main(String[] args) { // 根对象用LinkedHashMap,保证插入顺序 Map<String, Object> jsonObj = new LinkedHashMap<>(); jsonObj.put("first", "John"); jsonObj.put("last", "Smith"); jsonObj.put("age", 25); // 构造手机号数组 List<Map<String, String>> phoneNumbers = new ArrayList<>(); // 每个手机号单独新建map实例,避免覆盖 Map<String, String> homePhone = new LinkedHashMap<>(); homePhone.put("type", "home"); homePhone.put("number", "212 555-1234"); phoneNumbers.add(homePhone); Map<String, String> faxPhone = new LinkedHashMap<>(); faxPhone.put("type", "fax"); faxPhone.put("number", "646 555-4567"); phoneNumbers.add(faxPhone); jsonObj.put("phoneNumbers", phoneNumbers); // 直接用Gson序列化,输出顺序和插入顺序完全一致 Gson gson = new Gson(); String json = gson.toJson(jsonObj); System.out.println(json); } }
如果想要更规范的写法,也可以定义对应的实体类来存储数据,Gson默认会按类字段的声明顺序序列化,同样能保证顺序:
// 手机号实体类 class PhoneNumber { private String type; private String number; // 按需添加构造方法、getter、setter } // 用户实体类 class User { private String first; private String last; private Integer age; private List<PhoneNumber> phoneNumbers; // 按需添加构造方法、getter、setter }
补充说明
如果一定要继续使用org.json的类,可选择支持有序的OrderedJSONObject实现替换原生的JSONObject,但不推荐这类混合API的用法,容易出现更多兼容性问题。
内容的提问来源于stack exchange,提问作者Michal
相关产品推荐
相关产品推荐

