2016-08-14 215 views
2

我有一个序列化到JSON的问题,我的复杂对象包含另一个复杂对象的Map。我正在使用JAXB和MOXY。这里是我的课:我想序列 根类/反序列化:JAXB映射将复杂对象映射到JSON

@XmlRootElement 
@XmlSeeAlso(ComplexBean.class) 
@XmlAccessorType(XmlAccessType.FIELD) 
public class MapBean implements Serializable { 

    @XmlJavaTypeAdapter(MapAdapter.class) 
    @XmlElement 
    private Map<String, ComplexBean> complexBeans; 

我ComplexBean类(getter/setter方法省略):

public class ComplexBean implements Serializable { 
    private String name; 
    private String surName; 
    private double weight; 

MapAdapter类:

public class MapAdapter extends XmlAdapter<Element, Map<String, ComplexBean>> { 

private DocumentBuilder documentBuilder; 

public MapAdapter() throws Exception { 
    documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 
} 

public Element marshal(Map<String, ComplexBean> map) throws Exception { 
    Document document = documentBuilder.newDocument(); 
    Element rootElement = document.createElement("complexBeans"); 
    document.appendChild(rootElement); 
    for(Map.Entry<String, ComplexBean> entry : map.entrySet()) { 
     Element childElement = document.createElement(entry.getKey()); 
     ComplexBean complexBean = entry.getValue(); 

     Attr nameAttribute = document.createAttribute("name"); 
     nameAttribute.setValue(complexBean.getName()); 
     childElement.setAttributeNode(nameAttribute); 

     Attr surNameAttribute = document.createAttribute("surName"); 
     surNameAttribute.setValue(complexBean.getSurName()); 
     childElement.setAttributeNode(surNameAttribute); 

     Attr weightAttribute = document.createAttribute("weight"); 
     weightAttribute.setValue(String.valueOf(complexBean.getWeight())); 
     childElement.setAttributeNode(weightAttribute); 

     rootElement.appendChild(childElement); 
    } 
    return rootElement; 
} 

public Map<String, ComplexBean> unmarshal(Element element) throws Exception { 
    System.out.println("In unmarshaller"); 
    Map<String, ComplexBean> complexBeans = new HashMap<String, ComplexBean>(); 
    return null; 
} 
} 

而我的主要方法:

public static void main(String[] args) throws Exception { 
    Map<String, Object> jaxbProperties = new HashMap<String, Object>(); 
    jaxbProperties.put(JAXBContextProperties.MEDIA_TYPE, MediaType.APPLICATION_JSON); 
    jaxbProperties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false); 
    javax.xml.bind.JAXBContext jc = JAXBContext.newInstance(new Class[] {MapBean.class}, jaxbProperties); 

    Marshaller marshaller = jc.createMarshaller(); 
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 

    MapBean mapBean = getMapBean(); 

    Writer writer = new StringWriter(); 
    marshaller.marshal(mapBean, writer); 
    String json = writer.toString(); 
    System.out.println("Output JSON: "); 
    System.out.println(json); 

    StreamSource streamSource = new StreamSource(json); 
    Unmarshaller unmarshaller = jc.createUnmarshaller(); 
    MapBean unmarshalledMapBean = unmarshaller.unmarshal(streamSource, MapBean.class).getValue(); 
    System.out.println(unmarshalledMapBean); 
} 

所以,当我跑我的主要方法,编组返回这样JSON:

{ 
    "complexBeans" : { 
     "first" : { 
     "name" : "cbName1", 
     "surName" : "cbSurName1", 
     "weight" : "50.5" 
     }, 
     "second" : { 
     "name" : "cbName2", 
     "surName" : "cbSurName2", 
     "weight" : "10.5" 
     } 
    } 
} 

但umarshaller不会调用解组方法MapAdapter类和失败,出现异常:

Caused by: Exception [EclipseLink-25004] (Eclipse Persistence Services - 2.6.1.v20150916-55dc7c3): org.eclipse.persistence.exceptions.XMLMarshalException 
Exception Description: An error occurred unmarshalling the document 
Internal Exception: java.net.MalformedURLException: no protocol: { 
    "complexBeans" : { 
     "first" : { 
     "name" : "cbName1", 
     "surName" : "cbSurName1", 
     "weight" : "50.5" 
     }, 
     "second" : { 
     "name" : "cbName2", 
     "surName" : "cbSurName2", 
     "weight" : "10.5" 
     } 
    } 
} 
    at org.eclipse.persistence.exceptions.XMLMarshalException.unmarshalException(XMLMarshalException.java:120) 
    at org.eclipse.persistence.internal.oxm.record.json.JsonStructureReader.parse(JsonStructureReader.java:156) 
    at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:863) 
    at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:710) 
    at org.eclipse.persistence.internal.oxm.XMLUnmarshaller.unmarshal(XMLUnmarshaller.java:643) 
    at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:339) 
    ... 1 more 
    at java.net.URL.<init>(URL.java:586) 
    at java.net.URL.<init>(URL.java:483) 
    at java.net.URL.<init>(URL.java:432) 
    at org.eclipse.persistence.internal.oxm.record.json.JsonStructureReader.parse(JsonStructureReader.java:127) 
    at org.eclipse.persistence.internal.oxm.record.json.JsonStructureReader.parse(JsonStructureReader.java:154) 
    ... 5 more 

所以,请帮我解开我的json到MapBean对象。我的错误是什么?

回答

0

您的StreamSource调用在main方法中是错误的。您直接将json字符串传递给StreamSource构造函数。

这是你有什么currently--

StreamSource streamSource = new StreamSource(String json); 

你应该有这样的事情每StreamSource specification以下为

StreamSource streamSource = new StreamSource("file location/URL"); 

或者

StreamSource streamSource = new StreamSource(File); 
+1

太谢谢你了!你拯救了我的一天。我甚至不能认为我错误地创建了StreamSource。我已经用不同的MapAdapter整理了很多选项,但是错误发生在完全不同的地方! –