0

Given the following example JSON:

{
  "aud": "you",
  "exp": 1300819380,
  "user": {
    "name": "Joe",
    "address": {
        "street": "1234 Main Street",
        "city": "Anytown",
        "state": "CA",
        "postalCode": 94401
    }
  }
}

and the Java interface:

public interface Deserializer {
    Map<String,Object> deserialize(String json);
}

Using Jackson, how do I implement deserialize such that it returns a map of name/value pairs, but converts just the user field into a Java User domain object such that the following is possible:

Map<String,Object> map = deserializer.deserialize(json);
assert map.get("user") instanceof User;

The idea is that the top-level name/value pairs can be anything and are unstructured and we don't want to force a domain model. But if a user member exists, we do want that member value to be unmarshalled into a User domain instance.

Additionally, if possible, I really don't want to have to modify the deserialize implementation if the User domain model changes (e.g. if a field is added or removed over time).

Les Hazlewood
  • 18,480
  • 13
  • 68
  • 76

1 Answers1

1

Using Jackson, how do I implement deserialize such that it returns a map of name/value pairs, but converts just the user field into a Java User domain object [...]

One possible way to do it without writing custom deserializers would be:

@Override
public Map<String, Object> deserialize(String json) throws IOException {

    Map<String, Object> map =
            mapper.readValue(json, new TypeReference<Map<String, Object>>() {});

    Optional<Object> optional = Optional.ofNullable(map.get("user"));
    if (optional.isPresent()) {
        User user = mapper.convertValue(optional.get(), User.class);
        map.put("user", user);
    }

    return map;
}

If the user property is present in the JSON, it's mapped to a User instance and then replaced in the map.

cassiomolin
  • 124,154
  • 35
  • 280
  • 359