5

I'm using Jackson to deserialize JSON from a ReST API to Java objects using Jackson.

The issue I've run into is that one particular ReST response comes back wrapped in an object referenced by a numeric identifier, like this:

{
  "1443": [
    /* these are the objects I actually care about */
    {
      "name": "V1",
      "count": 1999,
      "distinctCount": 1999
      /* other properties */
    },
    {
      "name": "V2",
      "count": 1999,
      "distinctCount": 42
      /* other properties */
    },
    ...
  ]
}

My (perhaps naive) approach to deserializing JSON up until this point has been to create mirror-image POJOs and letting Jackson map all of the fields simply and automatically, which it does nicely.

The problem is that the ReST response JSON has a dynamic, numeric reference to the array of POJOs that I actually need. I can't create a mirror-image wrapper POJO because the property name itself is both dynamic and an illegal Java property name.

I'd appreciate any and all suggestions for routes I can investigate.

Nate Vaughan
  • 3,471
  • 4
  • 29
  • 47
  • A) Your JSON is invalid: Missing a `]`. B) Use an object array to prevent the issue you have (if I understand enough of your sample since it is a bit limited) – Norbert Feb 29 '16 at 00:28
  • A) Thanks; I've updated the sample JSON B) Sure, an array of objects is exactly my aim, but I can't actually get to the array at all, since it's referenced by a property name that is both dynamic and illegal in Java – Nate Vaughan Feb 29 '16 at 01:14

2 Answers2

4

The easiest solution without custom deserializers is to use @JsonAnySetter. Jackson will call the method with this annotation for every unmapped property.

For example:

public class Wrapper {
  public List<Stuff> stuff;

  // this will get called for every key in the root object
  @JsonAnySetter
  public void set(String code, List<Stuff> stuff) {
    // code is "1443", stuff is the list with stuff
    this.stuff = stuff;
  }
}

// simple stuff class with everything public for demonstration only
public class Stuff {
  public String name;
  public int count;
  public int distinctCount;
}

To use it you can just do:

new ObjectMapper().readValue(myJson, Wrapper.class);

For the other way around you can use @JsonAnyGetter which should return a Map<String, List<Stuff>) in this case.

rve
  • 5,897
  • 3
  • 40
  • 64
1

I think the easiest solution is to use a custom JsonDeserializer. It allows you to parse the input step by step and to extract only those information you need to build your object.

Here is a simple example how to implement a custom deserializer: custom jackson deserializer

Community
  • 1
  • 1
Awita
  • 334
  • 2
  • 8