使用Gson反序列化具有映射的JSON对象

时间:2013-11-22 20:55:13

标签: java json hashmap gson

我在网上搜索了一个解决方案,但是,我发现的答案只有在解析的JSON文件只是一张地图时才有用。

我想知道是否有办法解析具有HashMap的对象以及其他数据。

例如:

public class Data
{
  String aName;
  HashMap<String, Object> objects;
  List<String> aExpressions;
}

我可以解析名称和表达式,但我不知道如何解析整个JSON对象。

我认为它与类型标记有关,但只有在整个对象为HashMap时才有效。

2 个答案:

答案 0 :(得分:1)

您班级中HashMap的存在并不会改变Gson将其转换为json的方式。

data d = new data();
//set some values

String json = new Gson().toJson(d);
data d2 = new Gson().fromJson( json, data.class);

这就是它。

答案 1 :(得分:1)

Since

  

JSON可以表示四种基本类型(字符串,数字,   布尔值,以及null)和两种结构化类型(对象和数组)。

     

字符串是零个或多个Unicode字符的序列   [UNICODE]。

     

对象是零个或多个名称/值的无序集合   对,其中名称是字符串,值是字符串,数字,
  boolean,null,object或array。

     

数组是零个或多个值的有序序列。

Gson采取两种方式:

  1. 你可以让Gson反序列化创建地图,列表和基元的组合或
  2. 您可以准确指定所需的对象类型,通过反射,它将填充所需的对象。
  3. 您可以混合使用这两种方法,当然您可以做更多的事情来解决所有解析案例(例如使用自定义类型适配器)。

    我准备了一个使用你的类的例子,它展示了Gson如何使用map / list / primitives的组合解析你的数据或传递你的类(具有混合方法)。

    package stackoverflow.questions;
    
    import java.util.*;
    
    import com.google.gson.Gson;
    
    public class Q20154323 {
    
       public static class Data {
          public String aName;
          public HashMap<String, Object> objects;
          public List<String> aExpressions;
    
          @Override
          public String toString() {
             return "Data [aName=" + aName + ", objects=" + objects + ", aExpressions=" + aExpressions + "]";
          }
    
       }
    
       public static void main(String[] args) {
    
          Data d = new Data();
          d.aName = "Test";
          d.objects = new HashMap<>();
          d.aExpressions = new ArrayList<>();
    
          d.objects.put("key1", 1L);
          d.objects.put("key2", new Date());
          d.aExpressions.add("Stack");
          d.aExpressions.add("Overflow");
    
          Gson g = new Gson();
          String json = g.toJson(d);
          System.out.println("As JSON: " +json);
    
          Data d2 = g.fromJson(json, Data.class);
          System.out.println("As \"casted\" data type: " + d2);
    
          Object o3 = g.fromJson(json, Object.class);
          System.out.println("As \"free\" object: " + o3);
    
       }
    
    }
    

    这是执行。它向您展示了解析我使用您的初始类创建的JSON字符串的两种方法。

    As JSON: {"aName":"Test","objects":{"key2":"Nov 23, 2013 1:33:23 AM","key1":1},"aExpressions":["Stack","Overflow"]}
    As "casted" data type: Data [aName=Test, objects={key2=Nov 23, 2013 1:33:23 AM, key1=1.0}, aExpressions=[Stack, Overflow]]
    As "free" object: {aName=Test, objects={key2=Nov 23, 2013 1:33:23 AM, key1=1.0}, aExpressions=[Stack, Overflow]}
    

    您可以根据需要使用其中一种方法。

    关于TypeToken,由于泛型擦除,类似这样的

      List<Data> list = new Gson().parse(aJsonString, List<Data>.class)
    

    不起作用,你必须做类似

    的事情
      Type listType = new TypeToken<List<Data>>() {}.getType();
      List<Data> list = new Gson().parse(aJsonString, listType.class)
    

    但是,如果您的JSON是一个数组并且您想将其反序列化为自定义类列表,那么这种情况非常适用。