使用Gson或嵌套的内部类反序列化内部类中的任意对象json数组

时间:2010-12-17 12:13:17

标签: arrays list nested gson deserialization

当我尝试用Gson反序列化一个Json字符串时,我遇到了麻烦。字符串就是这样的 (注意:我只是简化了它,但是留下我遇到麻烦的部分,因此,可能存在Json语法错误,但我已经通过在线验证器检查了我正在使用的字符串是否正常):

// let's call this "container" json element
{
"context": "context", 
"cpuUsage": cpuUsageValue,  
"name": "thename",
"rates": {
    "definition": [
        {
        "key": "name",
        "type": "string"
        },
        {
        "key": "rate",
        "type": "double"
        }       
    ]
    "rows": [
        {
        "name": "thename1",
        "rate": therate
        },
        {
        "name": "thename2",
        "rate": therate2
        }
    ]
}

现在,我遇到的问题是当我尝试反序列化json数组(“definition”和“rows”)时。其余字段在反序列化中获得适当的值。 我正在使用的类定义如下(为简单起见,没有getter / setter):

public class Container
{
   private String context;
   private Double cpuUsage;
   private String name;   
   private RateContainer rates;

   public Container()
   {

   }
}

RateContainer(内部静态类到类Container,根据Gson规范):

public static class RateContainer
{
    private List<DefinitionContainer> definition;
    private List<RowsContainer> rows;

    public static class DefinitionContainer
    {
        String key;
        String type;

        public DefinitionContainer()
        {
        }
    }

    public static class RowsContainer
    {
        String name;
        Double rate; 

        public RowsContainer()
        {
        }
    }

    public RateContainer()
    {
    }
}

要解析Json字符串,我使用:

Container container = gson.fromJson(containerString, Container.class);

我得到以下异常:

Expecting object found: [{"key":"name","type":"string"},{"key":"rate","type":"double"}]

看起来在类定义中必须有一些不能正常工作的东西。我已经检查了Gson API,我知道,为了反序列化列表,通常要做的是:

Type collectionType = new TypeToken<Collection<Integer>>(){}.getType();
Collection<Integer> ints2 = gson.fromJson(json, collectionType);

所以我想也许我可以先使用以下内容获取这些数组:

JsonElement element = containerJsonElement.getAsJsonObject().get("rates");

然后得到“定义”和“行”,但我更喜欢将所有内容保存在Container对象中。 有没有办法以这种方式反序列化这些列表? 类定义中有什么问题吗?

提前谢谢大家!

1 个答案:

答案 0 :(得分:6)

在回答原始问题中的一些事项时,请注意以下三点:

  1. Gson不需要反序列化到静态内部类。
  2. 如果要反序列化的类型是一个通用的集合,则只需要使用通用的TypeToken。如果要反序列化的类型只包含 这样的集合,则不需要使用通用的TypeToken
  3. 使用像Gson或Jackson这样的API的一个主要好处是Java数据结构与JSON的简单映射和序列化/反序列化。因此,可以避免明确使用JsonElement之类的组件。
  4. 将示例JSON更正为

    {
        "context": "context", 
        "cpuUsage": "cpuUsageValue",  
        "name": "thename",
        "rates": {
            "definition": [
                {
                    "key": "name",
                    "type": "string"
                },
                {
                    "key": "rate",
                    "type": "double"
                }       
            ],
            "rows": [
                {
                    "name": "thename1",
                    "rate": "therate"
                },
                {
                    "name": "thename2",
                    "rate": "therate2"
                }
            ]
        }
    }
    

    ...然后按照预期简单地反序列化(和序列化)。

    import java.io.FileReader;
    import java.util.List;
    
    import com.google.gson.Gson;
    
    public class Foo
    {
      public static void main(String[] args) throws Exception
      {
        Gson gson = new Gson();
        Container container = gson.fromJson(new FileReader("input.json"), Container.class);
        System.out.println(gson.toJson(container));
      }
    }
    
    class Container
    {
      private String context;
      private String cpuUsage;
      private String name;
      private Rates rates;
    }
    
    class Rates
    {
      private List<Definition> definition;
      private List<Row> rows;
    }
    
    class Definition
    {
      private String key;
      private String type;
    }
    
    class Row
    {
      private String name;
      private String rate;
    }