我正在尝试使用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 field "736" (class WikipediaPages), not marked as ignorable (one known property: "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;
}
}
我使用Jackson Mixin来应用注释:
public interface WikipediaPagesMixIn {
@JsonAnyGetter
Map<String, WikipediaPage> getWikipediaPageMap();
@JsonAnySetter
void setWikipediaPageMap(Map<String, WikipediaPage> wikipediaPageMap);
}
编辑2:根据要求提供更多代码:
public class JacksonBuilder {
private static ObjectMapper objectMapper;
public static ObjectMapper getObjectMapper() {
if(objectMapper == null) {
objectMapper = new ObjectMapper();
objectMapper.registerModule(new WikipediaModule());
}
return objectMapper;
}
}
public class WikipediaModule extends SimpleModule {
public WikipediaModule() {
super("WikipediaModule", new Version(1, 0, 0, null, "net.ryanmorrison", "sentience"));
}
@Override
public void setupModule(SetupContext setupContext) {
setupContext.setMixInAnnotations(WikipediaPage.class, WikipediaPageMixIn.class);
setupContext.setMixInAnnotations(WikipediaPages.class, WikipediaPagesMixIn.class);
setupContext.setMixInAnnotations(WikipediaQuery.class, WikipediaQueryMixIn.class);
setupContext.setMixInAnnotations(WikipediaResult.class, WikipediaResultMixIn.class);
}
}
public class WikipediaResult {
private WikipediaQuery wikipediaQuery;
public WikipediaQuery getWikipediaQuery() {
return wikipediaQuery;
}
public void setWikipediaQuery(WikipediaQuery wikipediaQuery) {
this.wikipediaQuery = wikipediaQuery;
}
}
public interface WikipediaResultMixIn {
@JsonProperty("query")
WikipediaQuery getWikipediaQuery();
}
答案 0 :(得分:2)
要回答异常的根本原因,@JsonAnySetter
javadoc状态
可用于定义非静态的标记注释, 双参数方法(属性的第一个参数名称,第二个值为 设置),[...]
因此,使用像这样的mixin
@JsonAnySetter
void setWikipediaPageMap(Map<String, WikipediaPage> wikipediaPageMap);
未注册,因此找不到该属性。
老实说,如果您控制数据类,请不要使用mixins。您可以直接映射字段,如下所示。
我不知道你是如何使用mixin的,但下面的内容适用于我
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]}
Page
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<String, Page>
作为字段放在query
和pages
JSON元素的某个包装类中。