I want to marshall a java object to xml string.
Therefore I have been given a schema from which I generate the JAXB classes.
There is a set method(corresponding to an element of type hexbinary in schema) where I have to set a string.
The string size is about 2566.
After setting data into the object via the setter methods, I call the marshaller passing stringWriter argument.
But on printing stringWriter, I see that it is truncated. I don’t see the entire 2566 characters.
What is wrong? Any ideas?
Thanx!
Update:
I think I found the problem. I have to find a suitable title as my reasoning of the problem was wrong!! The problem is the following:
I have a “hexbinary” element in my schema. The generated class has a corresponding set/get method. To set the value I had used HexEncodeString method of apache commons package and realized that the marshaller shows 36383639 in the hexbinary tag for a String “hi” whose actual Hex encoding is 6869 🙁 Thus, the problem is the xml after marshalling has a tag value with # of chars greater than the original and not getting truncated like I thought before!
Thanks to Blaise Doughan‘s code. I have modified it and reproduced this problem.
First an example schema:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="Root">
<xs:sequence>
<xs:element name="string" type="xs:string" minOccurs="0"/>
<xs:element name="a" type="xs:hexBinary" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
With this I generated the ObjectFactory class and Root class.
I had to modify the ObjectFactory class to include JAXBElement so that I can pass this to the Marshaller. With these I took the Demo class of Blaise Doughan and modified it as:
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Root.class);
// The object factory
ObjectFactory objFactory = new ObjectFactory();
Root root = new Root();
String str = new String("hi");
String val = Hex.encodeHexString(str.getBytes());
root.setString(str);
root.setArr(val.getBytes());
System.out.println("val="+val);
System.out.println("getString ="+root.getString());
System.out.println("getArr="+new String(root.getArr()));
// Marshal the object to a StringWriter
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "http://www.example.com/schema.xsd");
StringWriter stringWriter = new StringWriter();
marshaller.marshal(objFactory.createRoot(root),stringWriter);
// marshaller.marshal(root, stringWriter);
// Convert StringWriter to String
String xml = stringWriter.toString();
System.out.println(xml);
// Unmarshal the XML and check length of long String
Unmarshaller unmarshaller = jc.createUnmarshaller();
Root unmarshalledRoot = (Root) unmarshaller.unmarshal(new StringReader(xml));
System.out.println(root.getString().length());
System.out.println(root.getString());
System.out.println(new String(root.getArr()).length());
System.out.println(new String(root.getArr()));
}
}
The output I get is:
val=6869
getString =hi
getArr=6869
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns3:Root xsi:schemaLocation="http://www.example.com/schema.xsd" xmlns:ns3="http://example.com/root" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<string>hi</string>
<arr>36383639</arr>
</ns3:Root>
Exception in thread "main" javax.xml.bind.UnmarshalException: unexpected element (uri:"http://example.com/root", local:"Root"). Expected elements are (none)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:631)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:236)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:231)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:105)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(UnmarshallingContext.java:1038)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:467)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:448)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:137)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:501)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:400)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(XMLNSDocumentScannerImpl.java:626)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3103)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:922)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:511)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:808)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:119)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:200)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:173)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:137)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:194)
at example.Demo.main(Demo.java:43)
Why is arr tag 36383639 and not 6869?
NEW ANSWER
In your sample code
valis the hexBinary representation ofstr.getBytes(). But the value you are setting on thearrproperty is the bytes from the hex encoded String.I believe what you mean to do is the following:
Which will produce the following output
Put another way
Will output:
ORIGINAL ANSWER
I have not been able to reproduce the issue that you are seeing. I am using a
Stringsize of500000. Below is what I have tried (does this sample work for you?). Is it possible that the truncation is due to the console you are writing the long String to?Demo
Root
Output