From 384e3b576fa4c4f349c5fcde7ffaea16e53c1c97 Mon Sep 17 00:00:00 2001 From: Christof Rabensteiner Date: Wed, 8 May 2019 11:17:34 +0200 Subject: Fix Namespace Prefixes in Marshaled Messages (msg: instead of ns#:) - Implement own NamespacePrefixMapper that maps prefixes depending on whether a msg or a mzs object is being marshaled. - Namespaces are not hardcoded but extracted from jaxb's generated sources (somewhat indirect, can be considered a hack, but there's no public API to extract namespaces) --- src/main/java/at/gv/egiz/moazs/Marshaller.java | 10 ++-- .../java/at/gv/egiz/moazs/MoaZSPrefixMapper.java | 54 ++++++++++++++++++++++ .../at/gv/egiz/moazs/config/MarshallerConfig.java | 52 +++++++++++++++++++-- .../at/gv/egiz/moazs/Mzs2MsgConverterTest.java | 15 ++++-- 4 files changed, 117 insertions(+), 14 deletions(-) create mode 100644 src/main/java/at/gv/egiz/moazs/MoaZSPrefixMapper.java diff --git a/src/main/java/at/gv/egiz/moazs/Marshaller.java b/src/main/java/at/gv/egiz/moazs/Marshaller.java index c126f03..7e2ab17 100644 --- a/src/main/java/at/gv/egiz/moazs/Marshaller.java +++ b/src/main/java/at/gv/egiz/moazs/Marshaller.java @@ -1,8 +1,6 @@ package at.gv.egiz.moazs; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.oxm.jaxb.Jaxb2Marshaller; -import org.springframework.stereotype.Component; import javax.xml.transform.Result; import javax.xml.transform.stream.StreamResult; @@ -14,11 +12,13 @@ import java.io.StringWriter; * @author xerx593 * Source: https://stackoverflow.com/questions/44676532/how-to-use-spring-to-marshal-and-unmarshal-xml */ -@Component public class Marshaller { - @Autowired - private Jaxb2Marshaller marshaller; + private final Jaxb2Marshaller marshaller; + + public Marshaller(Jaxb2Marshaller marshaller) { + this.marshaller = marshaller; + } public String marshallXml(final T obj) { StringWriter sw = new StringWriter(); diff --git a/src/main/java/at/gv/egiz/moazs/MoaZSPrefixMapper.java b/src/main/java/at/gv/egiz/moazs/MoaZSPrefixMapper.java new file mode 100644 index 0000000..ef85989 --- /dev/null +++ b/src/main/java/at/gv/egiz/moazs/MoaZSPrefixMapper.java @@ -0,0 +1,54 @@ +package at.gv.egiz.moazs; + +import com.sun.xml.bind.marshaller.NamespacePrefixMapper; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.Map; + +@Component +public class MoaZSPrefixMapper extends NamespacePrefixMapper { + + private final Map map = new HashMap<>(); + + public MoaZSPrefixMapper() { + map.put(getMsgNamespaceUri(), "msg"); + map.put(getMsgPNamespaceUri(), "msgp"); + map.put(getMzsNamespaceUri(), "mzs"); + map.put(getMzsPNamespaceUri(), "mzsp"); + map.put(getDsigNamespaceUri(), "dsig"); + } + + public MoaZSPrefixMapper(boolean isMzs) { + this(); + map.put((isMzs) ? getMzsPNamespaceUri() : getMsgPNamespaceUri(), "p"); + map.put((isMzs) ? getMzsNamespaceUri() : getMsgNamespaceUri(), ""); + } + + @Override + public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) { + return map.getOrDefault(namespaceUri, suggestion); + } + + private String getMsgNamespaceUri() { + return new at.gv.zustellung.msg.xsd.ObjectFactory().createDeliveryRequest(null).getName().getNamespaceURI(); + } + + private String getMsgPNamespaceUri() { + return new at.gv.zustellung.msg.xsd.persondata.ObjectFactory().createPerson(null).getName().getNamespaceURI(); + } + + private String getMzsNamespaceUri() { + return new at.gv.zustellung.app2mzs.xsd.ObjectFactory().createDeliveryRequest(null).getName().getNamespaceURI(); + } + + private String getMzsPNamespaceUri() { + return new at.gv.zustellung.app2mzs.xsd.persondata.ObjectFactory().createAbstractPersonData(null).getName().getNamespaceURI(); + } + + private String getDsigNamespaceUri() { + return new org.w3._2000._09.xmldsig_.ObjectFactory().createCanonicalizationMethod(null).getName().getNamespaceURI(); + } + + +} diff --git a/src/main/java/at/gv/egiz/moazs/config/MarshallerConfig.java b/src/main/java/at/gv/egiz/moazs/config/MarshallerConfig.java index e6e3cc1..6fdd128 100644 --- a/src/main/java/at/gv/egiz/moazs/config/MarshallerConfig.java +++ b/src/main/java/at/gv/egiz/moazs/config/MarshallerConfig.java @@ -1,5 +1,9 @@ package at.gv.egiz.moazs.config; +import at.gv.egiz.moazs.Marshaller; +import at.gv.egiz.moazs.MoaZSPrefixMapper; +import com.sun.xml.bind.marshaller.NamespacePrefixMapper; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.oxm.jaxb.Jaxb2Marshaller; @@ -10,19 +14,57 @@ import java.util.HashMap; public class MarshallerConfig { @Bean - public Jaxb2Marshaller jaxb2Marshaller() { + public NamespacePrefixMapper msgMapper() { + return new MoaZSPrefixMapper(false); + } + + @Bean + public NamespacePrefixMapper mzsMapper() { + return new MoaZSPrefixMapper(true); + } + + @Bean + public Jaxb2Marshaller mzsJaxbMarshaller() { + Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); + + marshaller.setClassesToBeBound( + at.gv.zustellung.app2mzs.xsd.ObjectFactory.class, + at.gv.zustellung.app2mzs.xsd.persondata.ObjectFactory.class, + at.gv.zustellung.msg.xsd.ObjectFactory.class); + + marshaller.setMarshallerProperties(new HashMap() {{ + put(javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT, true); + put("com.sun.xml.bind.namespacePrefixMapper", mzsMapper()); + }}); + + return marshaller; + } + + @Bean + public Jaxb2Marshaller msgJaxbMarshaller() { Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); + marshaller.setClassesToBeBound( - at.gv.zustellung.msg.xsd.ObjectFactory.class, - at.gv.zustellung.msg.xsd.persondata.ObjectFactory.class, - at.gv.zustellung.app2mzs.xsd.ObjectFactory.class, - at.gv.zustellung.app2mzs.xsd.persondata.ObjectFactory.class); + at.gv.zustellung.msg.xsd.ObjectFactory.class, + at.gv.zustellung.msg.xsd.persondata.ObjectFactory.class); marshaller.setMarshallerProperties(new HashMap() {{ put(javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT, true); + put("com.sun.xml.bind.namespacePrefixMapper", msgMapper()); }}); return marshaller; } + @Bean + public Marshaller mzsMarshaller() { + return new Marshaller(mzsJaxbMarshaller()); + } + + @Bean + public Marshaller msgMarshaller() { + return new Marshaller(msgJaxbMarshaller()); + } + + } diff --git a/src/test/java/at/gv/egiz/moazs/Mzs2MsgConverterTest.java b/src/test/java/at/gv/egiz/moazs/Mzs2MsgConverterTest.java index 0c092aa..990559c 100644 --- a/src/test/java/at/gv/egiz/moazs/Mzs2MsgConverterTest.java +++ b/src/test/java/at/gv/egiz/moazs/Mzs2MsgConverterTest.java @@ -7,6 +7,7 @@ import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @@ -27,7 +28,11 @@ public class Mzs2MsgConverterTest { private Mzs2MsgConverter converter; @Autowired - private Marshaller marshaller; + private Marshaller mzsMarshaller; + + @Autowired + private Marshaller msgMarshaller; + @Test public void testCanConvertValidMzsRequestToMsgRequest() throws IOException { @@ -36,13 +41,15 @@ public class Mzs2MsgConverterTest { try (var inputStream = new BufferedInputStream(new FileInputStream(fileName))) { - JAXBElement mzsRequest = marshaller.unmarshallXml(inputStream); + JAXBElement mzsRequest = mzsMarshaller.unmarshallXml(inputStream); + + logger.info("mzs request: {}", mzsMarshaller.marshallXml(mzsRequest)); var msgRequest = converter.convert(mzsRequest.getValue()); var jaxbMsgRequest = new ObjectFactory().createDeliveryRequest(msgRequest); - String msgRequestXML = marshaller.marshallXml(jaxbMsgRequest); + String msgRequestXML = msgMarshaller.marshallXml(jaxbMsgRequest); logger.info("msg request: {}", msgRequestXML); @@ -57,7 +64,7 @@ public class Mzs2MsgConverterTest { try (var inputStream = new BufferedInputStream(new FileInputStream(fileName))) { - JAXBElement mzsRequest = marshaller.unmarshallXml(inputStream); + JAXBElement mzsRequest = mzsMarshaller.unmarshallXml(inputStream); converter.convert(mzsRequest.getValue()); -- cgit v1.2.3