tutorial javaee impl example ejemplo java-ee jaxb

java ee - javaee - JAXB Marshaller: la salida de StringWriter tiene un valor de etiqueta truncada



jaxb tutorial (1)

Quiero asignar un objeto java a una cadena xml. Por lo tanto, me dieron un esquema del cual genero las clases de JAXB. Hay un método set (que corresponde a un elemento de tipo hexbinary en el esquema) donde tengo que establecer una cadena. El tamaño de la cadena es de aproximadamente 2566. Después de configurar los datos en el objeto a través de los métodos setter, invoco el argumento marshaller passing stringWriter.

Pero al imprimir stringWriter, veo que está truncado. No veo los 2566 caracteres completos.

¿Qué está mal? ¿Algunas ideas?

Gracias!

Actualizar:

Creo que encontré el problema. ¡Tengo que encontrar un título adecuado ya que mi razonamiento del problema era incorrecto! El problema es el siguiente: Tengo un elemento "hexbinary" en mi esquema. La clase generada tiene un método set / get correspondiente. Para establecer el valor, he usado el método HexEncodeString del paquete apache commons y me di cuenta de que el marcador muestra 36383639 en la etiqueta hexbinary para un String "hola" cuya codificación Hex real es 6869 :( Por lo tanto, el problema es que el xml después de calcular tiene una etiqueta valor con # caracteres más grandes que el original y sin truncar como pensé antes.

Gracias al código de Blaise Doughan . Lo he modificado y reproducido este problema.

Primero un esquema de ejemplo:

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

Con esto genere la clase ObjectFactory y la clase Root. Tuve que modificar la clase ObjectFactory para incluir JAXBElement para poder pasar esto al Marshaller. Con estos tomé la clase Demo de Blaise Doughan y la modifiqué como:

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

El resultado que obtengo es:

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)

¿Por qué es arr etiqueta 36383639 y no 6869?


NUEVA RESPUESTA

En su código de muestra, val es la representación str.getBytes() de str.getBytes() . Pero el valor que está configurando en la propiedad arr es los bytes de la cadena codificada hexadecimal.

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

Creo que lo que quieres hacer es lo siguiente:

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

Que producirá la siguiente salida

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>

Dicho de otra manera

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

Se producirá:

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

RESPUESTA ORIGINAL

No he podido reproducir el problema que estás viendo. Estoy usando un tamaño de String de 500000 . Debajo está lo que he intentado (¿esta muestra funciona para usted?). ¿Es posible que el truncamiento se deba a la consola para la que está escribiendo la cadena larga?

Manifestación

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

Raíz

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

Salida

500000 500000