Заставить JAXB добавлять префикс динамического пространства имен ко всем дочерним элементам. ⇐ JAVA
Заставить JAXB добавлять префикс динамического пространства имен ко всем дочерним элементам.
I'm building a SOAP integration and am using JAXB to build the requests. For most parts I can annotate each field with the correct namespace and get JAXB to add namespace prefix.
Example:
@XmlAccessorType(XmlAccessType.FIELD) public SomeClass { @XmlElement(name = "field", namespace = "http://namespace.com") private String field; } In some cases, however, the service reuses large object structures under different namespaces. In these cases I want to reuse the same Java classes but have JAXB assign the correct namespace prefix to each field when marshalling. The correct namespace is determined by the field annotation in the enclosing object. (Note also that the objects might be in different packages. Not sure this is relevant.)
Example:
package some.package; @XmlAccessorType(XmlAccessType.FIELD) private class Root { @XmlElement(namespace = "first", name = "objectOne") private MyObject objectOne; @XmlElement(namespace = "second", name = "objectTwo") private MyObject objectTwo; } package some.other.package; @XmlRootElement(name = "rootA", namespace = "namspace-a") private static class MyObject { @XmlElement(name = "aString") private String aString; @XmlElement(name = "anotherString") private String anotherString; } In the above example the two objects of type MyObject have different namespace. I need the fields withing MyObject (and within every complex child) to have namespace prefix.
This code replicates the SOAP message rendering:
public class TestNamespace { public static void main(String[] args) throws Exception { new TestNamespace().testNamespaceRun(); } private void testNamespaceRun() throws Exception { Root request = new Root(new MyObject("aaaa", "AAAA"), new MyObject("bbbb", "BBBB")); } private String render(Root request) throws Exception { MessageFactory mf = MessageFactory.newInstance(); SOAPMessage sm = mf.createMessage(); SOAPPart sp = sm.getSOAPPart(); SOAPEnvelope se = sp.getEnvelope(); Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); JAXBContext context = JAXBContext.newInstance(Root.class, MyObject.class); Marshaller m = context.createMarshaller(); JAXBElement req = new JAXBElement(new QName("root-a-namespace", "rootA"), Root.class, request); m.marshal(req, doc); se.getBody().addDocument(doc); sm.saveChanges(); ByteArrayOutputStream s = new ByteArrayOutputStream(); sm.writeTo(s); return s.toString(); } } This is the output (pretty printed):
aaaa AAAA bbbb BBBB Note that the aString and anotherString fields are missing namespace prefix.
Question How can I tell JAXB to add namespace prefix to every element?
Further clarification: The SOAP service I'm calling does not accept my request when the namespace prefix is missing. I can't be sure that is the only reason but it's the only thing I know has changed from a working request to a failing one. The error message specifically points out the field with missing prefix:
Invalid content was found starting with element 'aString'. One of '{"first":aString}' is expected.
Edited for clarity
This question is different from suggested similar ones in that the namespace cannot be defined on package level as it differs by context. It also is not a problem about namespace declaration, only by enforcing prefix.
Источник: https://stackoverflow.com/questions/781 ... d-elements
I'm building a SOAP integration and am using JAXB to build the requests. For most parts I can annotate each field with the correct namespace and get JAXB to add namespace prefix.
Example:
@XmlAccessorType(XmlAccessType.FIELD) public SomeClass { @XmlElement(name = "field", namespace = "http://namespace.com") private String field; } In some cases, however, the service reuses large object structures under different namespaces. In these cases I want to reuse the same Java classes but have JAXB assign the correct namespace prefix to each field when marshalling. The correct namespace is determined by the field annotation in the enclosing object. (Note also that the objects might be in different packages. Not sure this is relevant.)
Example:
package some.package; @XmlAccessorType(XmlAccessType.FIELD) private class Root { @XmlElement(namespace = "first", name = "objectOne") private MyObject objectOne; @XmlElement(namespace = "second", name = "objectTwo") private MyObject objectTwo; } package some.other.package; @XmlRootElement(name = "rootA", namespace = "namspace-a") private static class MyObject { @XmlElement(name = "aString") private String aString; @XmlElement(name = "anotherString") private String anotherString; } In the above example the two objects of type MyObject have different namespace. I need the fields withing MyObject (and within every complex child) to have namespace prefix.
This code replicates the SOAP message rendering:
public class TestNamespace { public static void main(String[] args) throws Exception { new TestNamespace().testNamespaceRun(); } private void testNamespaceRun() throws Exception { Root request = new Root(new MyObject("aaaa", "AAAA"), new MyObject("bbbb", "BBBB")); } private String render(Root request) throws Exception { MessageFactory mf = MessageFactory.newInstance(); SOAPMessage sm = mf.createMessage(); SOAPPart sp = sm.getSOAPPart(); SOAPEnvelope se = sp.getEnvelope(); Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); JAXBContext context = JAXBContext.newInstance(Root.class, MyObject.class); Marshaller m = context.createMarshaller(); JAXBElement req = new JAXBElement(new QName("root-a-namespace", "rootA"), Root.class, request); m.marshal(req, doc); se.getBody().addDocument(doc); sm.saveChanges(); ByteArrayOutputStream s = new ByteArrayOutputStream(); sm.writeTo(s); return s.toString(); } } This is the output (pretty printed):
aaaa AAAA bbbb BBBB Note that the aString and anotherString fields are missing namespace prefix.
Question How can I tell JAXB to add namespace prefix to every element?
Further clarification: The SOAP service I'm calling does not accept my request when the namespace prefix is missing. I can't be sure that is the only reason but it's the only thing I know has changed from a working request to a failing one. The error message specifically points out the field with missing prefix:
Invalid content was found starting with element 'aString'. One of '{"first":aString}' is expected.
Edited for clarity
This question is different from suggested similar ones in that the namespace cannot be defined on package level as it differs by context. It also is not a problem about namespace declaration, only by enforcing prefix.
Источник: https://stackoverflow.com/questions/781 ... d-elements
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение