2012-08-27 31 views
3

我想將一個java對象編組爲xml字符串。 因此我得到了一個從中生成JAXB類的模式。 有一個設置方法(對應於模式中的hexbinary類型的元素),我必須設置一個字符串。 字符串大小約爲2566. 通過setter方法將數據設置到對象中後,我調用了傳遞字符串參數的編組器。JAXB Marshaller:StringWriter輸出具有截斷標記值

但是,在打印stringWriter,我看到它被截斷。我沒有看到整個2566個字符。

出了什麼問題?有任何想法嗎?

Thanx!

更新:

我想我找到了問題。我必須找到合適的標題,因爲我對問題的推理是錯誤的!問題如下: 我的模式中有一個「hexbinary」元素。生成的類具有相應的set/get方法。要設置我使用的Apache Commons包的HexEncodeString方法的值,並且意識到編組器在hexbinary標籤中顯示了一個字符串「hi」,其實際的十六進制編碼是6869 :(因此,問題是xml在編組後有一個標籤!用字符大於原來的,而不是#價值越來越被截斷像我以前的想法

由於布萊斯Doughan的代碼,我已經修改了它,並重現該問題

首先一個示例模式:

<?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> 

有了這個,我生成了t他是ObjectFactory類和Root類。 我不得不修改ObjectFactory類以包含JAXBElement,以便我可以將它傳遞給Marshaller。有了這些我把Demo類布萊斯Doughan和修改它爲:

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())); 
    } 

} 

我得到的輸出是:

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) 

爲什麼ARR標籤36383639,而不是6869?

回答

1

新的答案

在示例代碼valstr.getBytes()的的hexBinary表示。但是,您在arr屬性上設置的值是來自十六進制編碼的字符串的字節。

String str = new String("hi"); 
String val = Hex.encodeHexString(str.getBytes()); 
root.setString(str); 
root.setArr(val.getBytes()); 

我相信你的意思做的是以下幾點:

String str = new String("hi"); 
String val = Hex.encodeHexString(str.getBytes()); 
root.setString(str); 
root.setArr(str.getBytes()); 

將產生以下輸出

val=6869 
getString =hi 
getArr=hi 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<root xsi:schemaLocation="http://www.example.com/schema.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <string>hi</string> 
    <a>6869</a> 
</root> 

換句話說

String str = new String("hi"); 
    System.out.print("String: " + str); 
    System.out.println(" hexBinary: " + Hex.encodeHexString(str.getBytes())); 
    String val = Hex.encodeHexString(str.getBytes()); 
    System.out.print("String: " + val); 
    System.out.println(" hexBinary: " + Hex.encodeHexString(val.getBytes())); 

將輸出:

String: hi hexBinary: 6869 
String: 6869 hexBinary: 36383639 

原來的答案

我一直無法重現,你所看到的問題。我正在使用尺寸爲500000String。下面是我試過的(這個樣本是否適合你?)。是否有可能截斷是由於您正在編寫長字符串的控制檯?

演示

package forum12146217; 

import java.io.*; 
import javax.xml.bind.*; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Root.class); 

     // Build a long String 
     StringBuilder stringBuilder = new StringBuilder(); 
     for(int x=0; x<500000; x++) { 
      stringBuilder.append("a"); 
     } 
     Root root = new Root(); 
     root.setString(stringBuilder.toString()); 
     System.out.println(root.getString().length()); 

     // 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(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(unmarshalledRoot.getString().length()); 
    } 

} 

package forum12146217; 

import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
public class Root { 

    private String string; 

    public String getString() { 
     return string; 
    } 

    public void setString(String string) { 
     this.string = string; 
    } 

} 

輸出

500000 
500000 
+0

難道是字符串的本質是什麼?如該標記中的十六進制值是對象輸出流。我可以用這段代碼更新我的問題。 – user907810

+0

請確認一下,我已經更新了我的問題。 – user907810

+0

我將JAXBContext傳遞給編組器,而不是XmlRootElement。 XJC生成一個OnjectFactory類,我調用在@XmlElementDecl下定義的create方法,該方法返回一個JAXBElement ,然後傳遞給Marshaller。只有在這裏它會變得混亂。我怎樣才能找到合適的地方。有什麼建議麼? – user907810