Java 使用Jackson解析动态生成的JSON对象名

Java 使用Jackson解析动态生成的JSON对象名,java,json,jackson,Java,Json,Jackson,我正在尝试使用Jackson将一些MediaWiki上下文从JSON反序列化到POJO中。但是,问题是其中一个JSON对象名是本文的整数ID值,因此不能使用像@JsonProperty这样的注释,因为该值从来都不是常量 下面是一些示例JSON来描述我的意思: http://en.wikipedia.org/w/api.php?action=query&titles=Albert%20Einstein&prop=info&format=json&indexpageids { "query"

我正在尝试使用Jackson将一些MediaWiki上下文从JSON反序列化到POJO中。但是,问题是其中一个JSON对象名是本文的整数ID值,因此不能使用像
@JsonProperty
这样的注释,因为该值从来都不是常量

下面是一些示例JSON来描述我的意思:

http://en.wikipedia.org/w/api.php?action=query&titles=Albert%20Einstein&prop=info&format=json&indexpageids

{
    "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
            }
        }
    }
}
(MediaWiki建议添加&indexpageids参数以帮助解析,但我看不出它对我有什么用处。)

我尝试使用
@JsonAnyGetter
@JsonAnySetter
注释,但它们似乎没有帮助,抛出了相同的异常
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:Unrecognized字段“736”(类WikipediaPages),未标记为可忽略(一个已知属性:“wikipediaPage”)

谢谢你的帮助

编辑:以下是当前相关类的外观:

public class WikipediaPages {

    private Map<String, WikipediaPage> wikipediaPageMap = new HashMap<String, WikipediaPage>();

    public Map<String, WikipediaPage> getWikipediaPageMap() {
        return wikipediaPageMap;
    }

    public void setWikipediaPageMap(Map<String, WikipediaPage> wikipediaPageMap) {
        this.wikipediaPageMap = wikipediaPageMap;
    }
}

为了回答异常的根本原因,
@JsonAnySetter
javadoc声明

可用于定义非静态的标记注释, 双参数方法(属性的第一个参数名称,属性的第二个值 设置),[…]

因此,使用这样的mixin

@JsonAnySetter
void setWikipediaPageMap(Map<String, WikipediaPage> wikipediaPageMap);
其中
页面

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;
    }
}

剩下的就是将
Map
作为
query
pages
JSON元素的某个包装类中的一个字段。

Make
pages
a
Map
其中
Page
保存所有其他数据。相同的异常:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:unrecogned字段“38991692”(WikipediaPages类),未标记为可忽略(一个已知属性:“wikipediaPageMap”])
。只需使用相关代码编辑原始问题。如果使用顶部代码块,它也可以工作。我通过创建Jackson模块来应用mixin,在
setupContext
方法中添加每个mixin,并在
ObjectMapper
实例化中应用该模块。我希望与JSON反序列化代码的其余部分保持一致,并解决最初的问题。@ryan据我所知,发生错误的原因是Jackson不知道如何映射JSON元素名
736
。我有4个模型类,WikipediaResult用于顶级JSON,WikipediaQuery用于“查询”对象,WikipediaPages用于“页面”对象,WikipediaPages用于动态命名对象。我通过调用
WikipediaResult WikipediaResult=JacksonBuilder.getObjectMapper().readValue(getInputStreamFromConnection(buildURLFromQuery(query)),WikipediaResult.class)进行反序列化。从HTTP连接提供InputStream。JacksonBuilder只是实例化一个新的
ObjectMapper
实例,并将包含mixin的模块添加到其中。@Ryan我对此无能为力。通过编辑您的问题向我展示。演示如何设置
ObjectMapper
。我也想看看维基百科的结果。当然,我编辑了这个问题。谢谢你留下来帮忙。
@JsonAnySetter
void setWikipediaPageMap(Map<String, WikipediaPage> wikipediaPageMap);
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);
{736=Page [pageid=736, ns=0, title=Albert Einstein, contentmodel=wikitext, pagelanguage=en, touched=2014-01-05T03:14:23Z, lastrevid=588780054, counter=, length=106159]}
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;
    }
}