Parsing dynamically generated JSON object names with Jackson Parsing dynamically generated JSON object names with Jackson json json

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.