简体   繁体   中英

Parse nested JSON with genson

I'm trying to parse some JSON I get from a web API to Java objects and have some problems.

Here is the JSON:

{
  "d":{
     "results":[
        {
          "__metadata" { some metadata I'm not interested in },
          "attribute1":"attribute id 1",
          "attribute2:"attribute value 1"
        },
        {
          "__metadata" { some metadata I'm not interested in },
          "attribute1":"attribute id 2",
          "attribute2:"attribute value 2"
        }
      ]
   }
}

Now I want to map this data on the following to Java classes, so that the results is a Catalog object and the values in the result array are CatalogEntry objects:

public class Catalog {
  private final List<CatalogEntry> values;

  public Catalog() {
      values = null;
  }

  public Catalog(@JsonProperty("results") List<CatalogEntry> values) {
      super();
      this.values = values;
  }
}

public class CatalogEntry {
  private String attribute1;
  private String attribute2;

  public CatalogEntry() {}

  public CatalogEntry(@JsonProperty("attribute1") String attribute1, 
                      @JsonProperty("attribute2") String attribute2) {
    this.attribute1 = attribute1;
    this.attribute2 = attribute2;
  }
}

With the following line I try to deserialize the JSON string to a Catalog object:

Catalog catalog = genson.deserialize(json, Catalog.class);

After that I try to get the values in the Catalog object, but get a NullPointerException, because it seems to be empty. I think the deserialization has a problem with the "d" object in the JSON, but how do I fix this? Any help would be appreciated.

The problem is that you havee 2 constructors, one with no arguments and the other with the arguments. Genson in this situation picks the empty constructor. And as the properties are not visible and there are no setter then it will not populate the values.

So if you want Genson to use a specific constructor then you must annotate it with @JsonCreator. BTW, you can remove the JsonProperty("...") on the arguments if you configure Genson with this option:

Genson genson = new GensonBuilder()
  .useConstructorWithArguments(true)
  .create();

The other option would be to tell Genson to use private properties by doing this:

Genson genson = new GensonBuilder()
  .useFields(true, VisibilityFilter.PRIVATE)
  .create();

In that case you don't need the annotations on the constructor as Genson will use the no arg one. I recommend you the first option.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM