Serialización XML
La serialización de los tipos Java del Message Model a XML se realiza en última instancia usando JAXB del mismo modo que en muchos otros proyectos Java.
Sin embargo, existen advertencias y restricciones importantes, principalmente sobre cómo manejamos los tipos normalised. El manejo de estos detalles está encapsulado en un XMLMapper dedicado. Esta clase debe verse como el lugar central para serializar y deserializar desde XML hacia la representación Java del message model. Se puede acceder a una instancia de XMLMapper a través de la clase ISO20022MessageModel; esta instancia está preconfigurada con detalles de las Message Definitions y debe usarse directamente.
XMLMapper
Las clases del IPF IS020022 Message Model NO contienen namespaces codificados como típicamente hacen las generadas por XJC. Esta es una decisión de diseño consciente: los Message Components se comparten entre múltiples Message Definitions y queremos adoptar este principio en lugar de diseñar en su contra.
|
XJX & package.info
XJC y JAXB normalmente operan bajo la premisa de que un único paquete Java representa un namespace (Message Definition). Esto suele lograrse mediante un único package.info que aloja una anotación XMLSchema con el namespace de la Message Definition asociada y todos los Message Components referenciados. |
Un patrón de aplicación común basado en el agrupamiento por namespace de los tipos de una Message Definition era crear un único objeto JAXBContext que cubriera todas las Message Definitions desplegadas.
El XMLMapper adopta un enfoque nuevo que difiere de esto. Las clases subyacentes no tienen ningún namespace definido (como se detalla en Tipos normalizados). En su lugar, definimos un objeto JAXBContext separado por Message Definition, y asociamos estos contextos distintos por el namespace real del propio mensaje.
Esto nos permite determinar el tipo de mensaje correcto en función del namespace y luego deserializar completamente el contenido en el ámbito restringido de la Message Definition específica. Desde la perspectiva de uso, esto da como resultado la misma funcionalidad que la serialización JAXB tradicional (un único método para serializar/deserializar). La única diferencia es que el "namespacing" ahora se gestiona dentro de XMLMapper en lugar de dentro de JAXB.
Para las Message Definitions implementadas con el Message Model proporcionado, el comportamiento de XMLMapper funciona exactamente como se describe aquí; sin embargo, consulta las notas siguientes sobre Namespace Registration para posibles inconvenientes si se usa XMLMapper con cualquier otro tipo.
|
Namespace Registration
Los tipos de Message Definitions y sus namespaces deben registrarse previamente en la instancia de XMLMapper para usar todas las capacidades de serialización y deserialización. La instancia de XMLMapper proporcionada por ISO20022MessageModel está automáticamente preconfigurada con esta información para todas las Message Definitions soportadas. La deserialización sin especificar un tipo requiere que el namespace del mensaje de destino haya sido registrado en la instancia de XMLMapper antes de la solicitud de deserialización. Si XMLMapper se usa en cualquiera de estos casos:
Entonces puedes ver comportamientos como:
|
Deserialización
Acceder a la instancia de XMLMapper:
XMLMapper xmlMapper = ISO20022MessageModel.getInstance().xmlMapper();
Con namespace
Deserializar un String XML con namespace a un tipo explícito conocido:
Mensaje de ejemplo de entrada
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.09">
<CstmrCdtTrfInitn>
<GrpHdr>
<MsgId>MsgId0</MsgId>
</GrpHdr>
</CstmrCdtTrfInitn>
</Document>
String exampleXML = ...;
//com.iconsolutions.iso20022.message.definitions.payment_initiation.pain001.Document
Document instance = xmlMapper.fromXML(exampleXML, Document.class);
El XML también puede deserializarse como String XML sin especificar un tipo explícito.
|
Esto requiere que el string XML incluya el namespace |
Object instance = xmlMapper.fromXML(exampleXML);
Sin namespace
Deserializar un String XML sin namespace a un tipo explícito conocido
Mensaje de ejemplo de entrada
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Document>
<CstmrCdtTrfInitn>
<GrpHdr>
<MsgId>MsgId0</MsgId>
</GrpHdr>
</CstmrCdtTrfInitn>
</Document>
String exampleXML = ...;
//com.iconsolutions.iso20022.message.definitions.payment_initiation.pain001.Document
Document instance = xmlMapper.fromXML(exampleXML, Document.class);
Observa que NO es posible deserializar un XML sin namespace sin especificar un tipo explícito.
Serialización
Serializar una instancia a un String XML
Ten en cuenta que el XML resultante tendrá el namespace incluido solo si la Message Definition ha sido registrada en XMLMapper (esto es cierto para todas las Message Definitions proporcionadas, pero puede no serlo si XMLMapper se usa fuera del contexto de ISO20022MessageModel)
Document instance = Document.builder().cstmrCdtTrfInitn(
CustomerCreditTransferInitiationV09.builder().grpHdr(
GroupHeader85.builder().msgId("msggId123").build())
.build())
.build();
String xml = xmlMapper.toXML(instance);