问题
I am using eclipse link(v2.5.0) Dynamic JAXB to convert XML to JSON and viceversa.
customer.xsd
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="address" type="address"/>
<xs:element name="customer" type="customer"/>
<xs:complexType name="address">
<xs:sequence>
<xs:element name="city" type="xs:string" minOccurs="0"/>
<xs:element name="street" type="xs:string" minOccurs="0"/>
<xs:element name="type" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="customer">
<xs:sequence>
<xs:element ref="address" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
customer.xml
<?xml version="1.0" encoding="UTF-8"?>
<customer>
<name>Jane Doe</name>
<address>
<city>My Town</city>
<street>123 Any Street</street>
<type>work</type>
</address>
</customer>
customer.json
{
"address" : {
"city" : "My Town",
"street" : "123 Any Street",
"type" : "work"
}
}
MyCode
public class Demo {
public static void main(String[] args) {
try {
// create DynamicJAXBContext
FileInputStream xsdInputStream = new FileInputStream("D:\\GUI\\customer.xsd");
DynamicJAXBContext jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(xsdInputStream, null, null, null);
// Unmarshal XML--> Java
FileInputStream xmlInputStream = new FileInputStream("D:\\GUI\\customer.xml");
JAXBUnmarshaller unmarshaller = jaxbContext.createUnmarshaller();
JAXBElement<DynamicEntity> root = (JAXBElement)unmarshaller.unmarshal(xmlInputStream);
JAXBMarshaller marshaller = jaxbContext.createMarshaller();
DynamicEntity javaResponse = root.getValue();
Map namespaces = new HashMap();
// Marshal Java --> JSON
JAXBMarshaller jsonMarshaller = jaxbContext.createMarshaller();
jsonMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jsonMarshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/json");
jsonMarshaller.setProperty(MarshallerProperties.NAMESPACE_PREFIX_MAPPER, namespaces);
FileOutputStream jsonOutputStream = new FileOutputStream("D:\\GUI\\customer.json");
jsonMarshaller.marshal(javaResponse, jsonOutputStream);
// JSON->JAVA->XML
JAXBUnmarshaller jsonUnmarshaller = jaxbContext.createUnmarshaller();
jsonUnmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, "application/json");
jsonUnmarshaller.setProperty(UnmarshallerProperties.JSON_NAMESPACE_PREFIX_MAPPER, namespaces);
StreamSource json = new StreamSource("D:\\GUI\\customer.json");
JAXBElement<DynamicEntity> myroot = (JAXBElement)jsonUnmarshaller.unmarshal(json);
DynamicEntity myResponse = myroot.getValue();
marshaller.marshal(myResponse, System.out);
} catch (JAXBException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
Exception
Exception in thread "main" java.lang.NullPointerException
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:264)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:443)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:296)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parseRoot(JSONReader.java:166)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:125)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:140)
at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:778)
at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:666)
at org.eclipse.persistence.oxm.XMLUnmarshaller.unmarshal(XMLUnmarshaller.java:593)
at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:287)
at Demo.main(Demo.java:47)
My questions
1.Does eclipse link Dynamic JAXB officially support XML to JSON and viceversa conversions as I have tried above, as I could not see any such examples?
2.How to avoid the above nullpointer exception and still have an element named "type" defined as part of the schema? Is this a bug? Are there any workarounds? I have written the demo code only to highlight the same problem I face elsewhere where I use multiple XML schemas and require a namespace aware handling for JSON conversion.
回答1:
1.Does eclipse link Dynamic JAXB officially support XML to JSON and viceversa conversions as I have tried above, as I could not see any such examples?
EclipseLink JAXB (MOXy)'s Dynamic JAXB supports all of the same features as its regular JAXB including JSON-binding.
2.How to avoid the above nullpointer exception and still have an element named "type" defined as part of the schema? Is this a bug? Are there any workarounds? I have written the demo code only to highlight the same problem I face elsewhere where I use multiple XML schemas and require a namespace aware handling for JSON conversion.
You could change your code to the following:
// JSON->JAVA->XML
JAXBUnmarshaller jsonUnmarshaller = jaxbContext.createUnmarshaller();
jsonUnmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, "application/json");
// Since there is no root node in your JSON document you should set this flag
jsonUnmarshaller.setProperty(UnmarshallerProperties.JSON_INCLUDE_ROOT, false);
// Since there is no root node to uniquely identify the class you need
// to supply one in the unmarshal method. To get the "class" for a
// DynamicEntity you can do the following:
Class customerType = jaxbContext.getDynamicType("generated.Customer").getJavaClass();
StreamSource json = new StreamSource("src/forum17446153/customer.json");
JAXBElement<DynamicEntity> myroot = (JAXBElement)jsonUnmarshaller.unmarshal(json, customerType);
DynamicEntity myResponse = myroot.getValue();
// Since the customer type is named in the XML schema there isn't
// a root element associated with the type. This means you will need
// to wrap in in an instance of JAXBElement to marshal it.,
JAXBElement jaxbElementResponse = new JAXBElement(new QName("customer"), customerType, myResponse);
marshaller.marshal(jaxbElementResponse, System.out);
回答2:
Change
StreamSource json = new StreamSource("D:\\GUI\\customer.json");
to
File json = new File("D:\\GUI\\customer.json");
And it should work. :)
来源:https://stackoverflow.com/questions/17446153/dynamic-jaxb-support-to-convert-xml-to-json