Parsing dynamically generated JSON object names with Jackson
To answer the root cause of your exception, the @JsonAnySetter
javadoc states
Marker annotation that can be used to define a non-static, two-argument method (first argument name of property, second value to set), [...]
As such, using a mixin like this
@JsonAnySettervoid setWikipediaPageMap(Map<String, WikipediaPage> wikipediaPageMap);
doesn't register it and therefore the property isn't found.
Honestly, don't use mixins if you control the data classes. You can directly map the fields as I've shown below.
I don't know how you are using your mixin, but the following works for me
String json = "{ \"query\": { \"pageids\": [ \"736\" ], \"pages\": { \"736\": { \"pageid\": 736, \"ns\": 0, \"title\": \"Albert Einstein\", \"contentmodel\": \"wikitext\", \"pagelanguage\": \"en\", \"touched\": \"2014-01-05T03:14:23Z\", \"lastrevid\": 588780054, \"counter\": \"\", \"length\": 106159 } } } }";ObjectMapper mapper = new ObjectMapper();JsonNode node =mapper.readTree(json);node = node.get("query").get("pages");Map<String, Page> pages = mapper.readValue(node.traverse(), new TypeReference<Map<String, Page>>() {});System.out.println(pages);
prints
{736=Page [pageid=736, ns=0, title=Albert Einstein, contentmodel=wikitext, pagelanguage=en, touched=2014-01-05T03:14:23Z, lastrevid=588780054, counter=, length=106159]}
Where Page
is
class Page { private int pageid; private int ns; private String title; private String contentmodel; private String pagelanguage; private String touched; // this could be a Date, with the appropriate format configuration private int lastrevid; private String counter; private int length; @Override public String toString() { return "Page [pageid=" + pageid + ", ns=" + ns + ", title=" + title + ", contentmodel=" + contentmodel + ", pagelanguage=" + pagelanguage + ", touched=" + touched + ", lastrevid=" + lastrevid + ", counter=" + counter + ", length=" + length + "]"; } public int getPageid() { return pageid; } public void setPageid(int pageid) { this.pageid = pageid; } public int getNs() { return ns; } public void setNs(int ns) { this.ns = ns; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getContentmodel() { return contentmodel; } public void setContentmodel(String contentmodel) { this.contentmodel = contentmodel; } public String getPagelanguage() { return pagelanguage; } public void setPagelanguage(String pagelanguage) { this.pagelanguage = pagelanguage; } public String getTouched() { return touched; } public void setTouched(String touched) { this.touched = touched; } public int getLastrevid() { return lastrevid; } public void setLastrevid(int lastrevid) { this.lastrevid = lastrevid; } public String getCounter() { return counter; } public void setCounter(String counter) { this.counter = counter; } public int getLength() { return length; } public void setLength(int length) { this.length = length; }}
All that is left is to put the Map<String, Page>
as a field in some wrapper class for the query
and pages
JSON elements.