I’m trying to deserialize a JSON file with the format of
{ "English": { "hex": "FF0000" }, "Spanish": { "hex": "0000FF" }, "Japanese": { "hex": "FFFF00" } }
But I don’t want to create a class for each language (thousands) so I wrote a custom LanguageDeserializer
which gives me back the List<Language>
that I want
static class LanguageDeserializer extends StdDeserializer<ArrayList<Language>> { //... @Override public ArrayList<Language> deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException { final JsonNode node = jp.getCodec().readTree(jp); final Iterator<Map.Entry<String, JsonNode>> nodes = node.fields(); final ArrayList<Language> results = new ArrayList<>(); while (nodes.hasNext()) { // Builds up the object from the nodes results.add(builder.build()); } return results; }
I have a parent class to wrap the results:
public class LanguageWrapper { @JsonDeserialize(using = Language.LanguageDeserializer.class) public List<Language> languages = new ArrayList<>(); }
So when I try and use it
final LanguageWrapper languageWrapper = objectMapper.readValue(new ClassPathResource("data/languages.json").getFile(), LanguageWrapper.class);
The languages
list is always empty.
Can I do this without needing the LanguageDeserializer
or how do I make it work?
Advertisement
Answer
Yeah was clearly overthinking it. As @chrylis suggested a Map
was the right direction to go in.
Simple as:
final TypeReference<HashMap<String, Language>> typeRef = new TypeReference<>() {}; final HashMap<String, Language> hashMap = objectMapper.readValue(new ClassPathResource("data/languages.json").getFile(), typeRef);