Given a structure like this:
{
"nameOfObject": { "score": 100 },
"anotherObject": { "score": 30 }
}
Is it possible to map this to:
class Container {
Map<String, ScoreKeeper> scoreKeepers;
}
class ScoreKeeper {
String name;
int score;
}
So that you end up with the name
property of the ScoreKeeper
instances set to "nameOfObject"
and "anotherObject"
, respectively?
I am a firm believer in separating your POJOs from externalization. Read your JSON into a Map and then build you Container/ScoreKeeper objects like this (apols for any typos):
mapper = new ObjectMapper();
Map<String,Object> data = mapper.readValue(inputstream, Map.class);
Container c = new Container();
for(Map.Entry<String, Object> me : data.entrySet()) {
String key = me.getKey();
Map info = (Map) me.getValue();
ScoreKeeper sk = new ScoreKeeper();
sk.setName(key);
Integer q = info.get("score");
sk.setScore(q);
c.put(key, sk);
}
Alternative solution, where the key name
is set on the value object by using a custom Deserializer:
@Test
public void test() throws JsonParseException, JsonMappingException, IOException {
ObjectMapper mapper = new ObjectMapper();
Data data = mapper.readValue("{\"users\": {\"John\": {\"id\": 20}, \"Pete\": {\"id\": 30}}}", Data.class);
assertEquals(20, data.users.get("John").id);
assertEquals(30, data.users.get("Pete").id);
assertEquals("John", data.users.get("John").name);
assertEquals("Pete", data.users.get("Pete").name);
}
public static class Data {
@JsonDeserialize(contentUsing = Deser.class)
public Map<String, User> users;
}
public static class User {
public String name;
public int id;
}
public static class Deser extends JsonDeserializer<User> {
@Override
public User deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
String name = ctxt.getParser().getCurrentName();
User user = p.readValueAs(User.class);
user.name = name; // This copies the key name to the value object
return user;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With