2

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.

Markus Wilhelm
  • 171
  • 2
  • 2
  • 11

1 Answers1

0

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.

eugen
  • 5,856
  • 2
  • 29
  • 26
  • Thanks for your answer, can't currently try your tips, but will tomorrow when I'm back at work. – Markus Wilhelm Jun 14 '15 at 07:21
  • Hey I tried your tps by specifying the right constructor, but the values of the catalog are stillt not created. – Markus Wilhelm Jun 15 '15 at 07:22
  • Oh, I see that you have your catalog object is not the root of the json. Can you change your json to not have d: {results} but just {results}? Otherwise if all your incoming jsons will use d as key you can configure Genson with [wrapRootValues("d", "d")](http://owlike.github.io/genson/Documentation/Configuration/) – eugen Jun 15 '15 at 08:51
  • @MarkusWilhelm does this work for you? You can also use the JaxbBundle with wrapRootValues enabled and @XmlRootElement("d") on your Catalog class. – eugen Jun 16 '15 at 08:52
  • Thanks. I try it today, will answer later with the results. – Markus Wilhelm Jun 17 '15 at 05:53
  • @XmlRootElement("d") helped me to get my code working. Thank you for your help! – Markus Wilhelm Jun 17 '15 at 07:02