gpt4 book ai didi

jakarta-ee - JAXB 编码器 : StringWriter output has a truncated tag value

转载 作者:行者123 更新时间:2023-12-02 03:56:59 24 4
gpt4 key购买 nike

我想将 java 对象编码为 xml 字符串。因此,我获得了一个模式,我可以从中生成 JAXB 类。有一个 set 方法(对应于模式中 hexbinary 类型的元素),我必须在其中设置一个字符串。字符串大小约为 2566。通过 setter 方法将数据设置到对象后,我调用 marshaller 传递 stringWriter 参数。

但是在打印 stringWriter 时,我看到它被截断了。我没有看到完整的 2566 个字符。

怎么了?有什么想法吗?

谢谢!

更新:

我想我找到了问题所在。我必须找到一个合适的标题,因为我对问题的推理是错误的!!问题如下:我的架构中有一个“hexbinary”元素。生成的类有对应的set/get方法。要设置值,我使用了 apache commons 包的 HexEncodeString 方法,并意识到编码器在十六进制标记中显示 36383639 字符串“hi”,其实际十六进制编码为 6869 :( 因此,问题是编码后的 xml 有一个标记# of chars 的值大于原始值,并且没有像我之前想的那样被截断!

感谢 Blaise 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>

由此我生成了 ObjectFactory 类和 Root 类。我必须修改 ObjectFactory 类以包含 JAXBElement,以便我可以将它传递给 Marshaller。有了这些,我将 Blaise Doughan 的 Demo 类修改为:

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?

最佳答案

新答案

在您的示例代码中,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

原始答案

我无法重现您遇到的问题。我使用的 String 大小为 500000。以下是我尝试过的方法(此示例对您有用吗?)。截断是否可能是由于您正在向其中写入长字符串的控制台造成的?

演示

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

关于jakarta-ee - JAXB 编码器 : StringWriter output has a truncated tag value,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12146217/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com