2012-08-27 30 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