使用Jaxb/Jersey将动态JSON对象映射到Java POJO
问题描述:
我想使用Jaxb/Jersey将JSON-Response映射到我的Java对象。我有这样的JSON响应:使用Jaxb/Jersey将动态JSON对象映射到Java POJO
{
"fuzzy": false,
"hits": [
{ ... }
],
"filters": {
"category": {
"selected": false,
"values": { }
},
"id": "category",
"name": "Kategorie"
},
"shop": {
"selected": false,
"values": {
"7817": {
"count": 2,
"selected": false,
"numeric_sort_key": null,
"id": "7817",
"name": "AZUGA"
}
},
"id": "shop",
"name": "Shop"
},
"11223": {
"selected": false,
"values": { },
"id": "certificate",
"name": "Vertrauensgarantie"
},
"11334": {
"selected": false,
"values": {
"2290": {
"count": 1,
"selected": false,
"numeric_sort_key": null,
"id": "2290",
"name": "22.90"
}
},
"id": "price",
"name": "Preis"
}
},
"total_hits": 2
}
这是bean我想映射的JSON响应为:
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@XmlRootElement
public class RestBean {
@XmlElement
private String fuzzy;
@XmlElement
private List<HitsBean> hits;
@XmlElement
private Filters filters;
@XmlElement
private String total_hits;
}
的问题是,的子元素“过滤器”是动态的,这意味着无法事先知道子元素“11223”和“11334”的名称,因为它们是在运行时创建的。这里是我的过滤器豆:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlMixed;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name="filters")
@XmlAccessorType(XmlAccessType.FIELD)
public class Filters {
@XmlElement
private Filter category;
@XmlElement
private Filter shop;
@XmlAnyElement
@XmlMixed
private List<Filter> filt;
}
但注释@XmlAnyElement总是抛出了这样的错误:
23.04.2013 16:26:11 com.sun.jersey.spi.container.ContainerResponse mapMappableContainerException
SCHWERWIEGEND: The RuntimeException could not be mapped to a response, re-throwing to the HTTP container
org.w3c.dom.DOMException: INVALID_CHARACTER_ERR: An invalid or illegal XML character is specified.
at com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl.checkQName(CoreDocumentImpl.java:2582)
at com.sun.org.apache.xerces.internal.dom.ElementNSImpl.setName(ElementNSImpl.java:117)
at com.sun.org.apache.xerces.internal.dom.ElementNSImpl.<init>(ElementNSImpl.java:80)
at com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl.createElementNS(CoreDocumentImpl.java:2095)
at com.sun.org.apache.xalan.internal.xsltc.trax.SAX2DOM.startElement(SAX2DOM.java:164)
at com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.closeStartTag(ToXMLSAXHandler.java:204)
at com.sun.org.apache.xml.internal.serializer.ToSAXHandler.flushPending(ToSAXHandler.java:277)
at com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.startElement(ToXMLSAXHandler.java:646)
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerHandlerImpl.startElement(TransformerHandlerImpl.java:263)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.DomLoader.startElement(DomLoader.java:107)
...
我的问题是,我应该如何映射动态生成的JSON响应,在这种情况下, “11223”和“11334”?非常感谢你提前。
问候, Suparno
答
它使用杰克逊映射器和@JsonAnyGetter/@JsonAnySetter
(org.codehaus.jackson.annotate
封装)注解非常简单。
级过滤器
public class Filters {
private Filter category;
private Filter shop;
private Map<String, Filter> filt = new HashMap<String, Filter>();
@JsonAnyGetter
public Map<String, Filter> any() {
return filt;
}
@JsonAnySetter
public void set(String name, Filter value) {
filt.put(name, value);
}
// getters/setters for category and shop
}
此外,在所有类不使用@XmlAccessorType(XmlAccessType.FIELD)
序列化到JSON(这里使用getter/setter方法以及默认XmlAccessorType这一点很重要)。使用getter/setter对和默认存取器类型。
JSON的XML注释? – 2013-04-23 15:02:56
也许你可以使用'@ JsonDeserialize'或者用'ObjectMapper'注册你自己的模块? – Willy 2013-04-24 02:27:50
@Willy你是什么意思“自己的模块与ObjectMapper”? – 2014-06-26 13:27:14