泽西岛(哈希)地图的序列化程序使用?
我正在尝试将以下有效负载发布到基于Jersey的Web服务:
{ "firstname":"Jimmy", "lastname":"Johns", "addresses": [ { "street":"19 Mayberry Drive", "city":"Mayberry", "state":"nc", "postalcode":"27043", "country":"us", "addresstype":1 } ], "data": { "eyes":"blue", "hair":"brown", "sandwich":"roast beef" } }
我的泽西岛代码:
@POST public Response create( Person person ) { createBo( person ); <------- stopped here in debugger ...
就像泽西岛给我打电话一样停下来,我看到的地址正在冲刷出我正在寻找的东西(上面的JSON中有什么)。 但是,我的数据元组不存在。 我知道Jersey正在为Address es调用我的无参数构造函数,并且它的调用者正在被调用,但是我在夜间就像Jersey可能会或可能不会尝试使用这些随机(“数据”)元组一样在我的JSON中。 (我说“随机”,因为在不同的调用中,这些可能是“洞穴”:“深,黑”,“山”:“高,宽”等。这是我界面的一部分。)
为了充实我正在谈论的内容,请将这些POJO视为上述内容:
@XmlAccessorType( XmlAccessType.FIELD ) @XmlRootElement public class Person implements Serializable { @XmlElement private List addresses = new ArrayList(); @XmlElement private Map data = new HashMap(); ... @XmlRootElement public class Address implements Serializable { private String street; private String city; private String state; private String country; private String postalcode; private Integer addresstype; ...
注意:我不能做随机元组,因为我事先并不知道密钥是什么(而我将地址限制为街道 , 城市等)。
我需要的是泽西的HashMap的某种魔术序列化器,我似乎无法很好地理解文档如何编写一个或解决这个问题,同时仍然保持我的界面的灵活性。
我将不胜感激如何实现这一目标。
拉斯贝特曼
PS遗憾地注意到带有Jersey / JAXB / Jackson的Java.util.Map到JSON对象没有帮助,尽管它显示了很大的希望。
注意:我是EclipseLink JAXB(MOXy)的负责人,也是JAXB(JSR-222)专家组的成员。
如果您使用MOXy,以下内容将起作用,并且应该与任何其他JAXB提供程序一起使用。 此方法使用XmlAdapter
将java.util.Map
转换为org.w3c.dom.Element
。
MapAdapter
XmlAdapter
允许您将一个类的实例编组为另一个类的实例(请参阅: http : //blog.bdoughan.com/2010/07/xmladapter-jaxbs-secret-weapon.html )。
package forum11353790; import java.util.*; import java.util.Map.Entry; import javax.xml.bind.annotation.adapters.XmlAdapter; import javax.xml.parsers.*; import org.w3c.dom.*; public class MapAdapter extends XmlAdapter> { private DocumentBuilder documentBuilder; public MapAdapter() throws Exception { documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); } @Override public Element marshal(Map map) throws Exception { Document document = documentBuilder.newDocument(); Element rootElement = document.createElement("data"); document.appendChild(rootElement); for(Entry entry : map.entrySet()) { Element childElement = document.createElement(entry.getKey()); childElement.setTextContent(entry.getValue()); rootElement.appendChild(childElement); } return rootElement; } @Override public Map unmarshal(Element rootElement) throws Exception { NodeList nodeList = rootElement.getChildNodes(); Map map = new HashMap(nodeList.getLength()); for(int x=0; x
人
您指定字段/属性应通过@XmlJavaTypeAdapter
批注利用@XmlJavaTypeAdapter
。
package forum11353790; import java.io.Serializable; import java.util.*; import javax.xml.bind.annotation.*; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; @XmlAccessorType( XmlAccessType.FIELD ) @XmlRootElement public class Person implements Serializable { private String firstname; private String lastname; private List< Address > addresses = new ArrayList< Address >(); @XmlAnyElement @XmlJavaTypeAdapter(MapAdapter.class) private Map< String, String > data = new HashMap< String, String >(); }
地址
package forum11353790; import java.io.Serializable; import javax.xml.bind.annotation.*; @XmlAccessorType(XmlAccessType.FIELD) public class Address implements Serializable { private String street; private String city; private String state; private String country; private String postalcode; private Integer addresstype; }
jaxb.properties
要将MOXy指定为JAXB提供程序,您需要在与域模型相同的包中包含一个名为jaxb.properties
的文件,并带有以下条目(请参阅: http : //blog.bdoughan.com/2011/05/specifying-eclipselink- moxy-as-your.html )。
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
演示
下面是一个独立的示例,您可以运行以certificate一切正常。
package forum11353790; import java.io.FileInputStream; import java.util.*; import javax.xml.bind.*; import javax.xml.transform.stream.StreamSource; import org.eclipse.persistence.jaxb.JAXBContextProperties; public class Demo { public static void main(String[] args) throws Exception { Map properties = new HashMap(2); properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json"); properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false); JAXBContext jc = JAXBContext.newInstance(new Class[] {Person.class}, properties); Unmarshaller unmarshaller = jc.createUnmarshaller(); StreamSource json = new StreamSource(new FileInputStream("src/forum11353790/input.json")); Person person = unmarshaller.unmarshal(json, Person.class).getValue(); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(person, System.out); } }
input.json /输出
{ "firstname" : "Jimmy", "lastname" : "Johns", "addresses" : [ { "street" : "19 Mayberry Drive", "city" : "Mayberry", "state" : "nc", "country" : "us", "postalcode" : "27043", "addresstype" : 1 } ], "data" : { "sandwich" : "roast beef", "hair" : "brown", "eyes" : "blue" } }
MOXy和JAX-RS / Jersey
您可以通过利用MOXyJsonProvider
类在JAX-RS环境中利用MOXyJsonProvider
:
jackson为您提供设施。 您可以通过将以下内容添加到Application
类来强制它。 请注意,这可能会禁用@Path
注释类的自动定位。
@Override public Set