I am using Jaxb2 and Spring. I am trying to unmount some XML that are sent by two of my clients.
So far, I only had to deal with one client that sent some xml:
<foo xmlns="com.acme"> <bar>[...]</bar> <foo>
which is associated with POJO as follows:
@XmlType(name = "", propOrder = {"bar"}) @XmlRootElement(name = "Foo") public class Foo { @XmlElement(name = "Bar") private String bar; [...] }
I found that the previous developer hardcoded the namespace in unmarshaller to make it work.
Now the second client sends the same XML, but changes the namespace!
<foo xmlns="com.xyz"> <bar>[...]</bar> <foo>
Obviously, unmarshaller cannot undo the token because it expects {com.acme}foo instead of {com.xyz}foo . Unfortunately, asking the client to change the XML is not an option.
What I tried:
1) In application-context.xml I was looking for a configuration that would allow me to ignore the namespace, but could not find it:
<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller"> <property name="packagesToScan"> <list> <value>com.mycompany.mypkg</value> </list> </property> <property name="marshallerProperties"> <map> <entry key="???"><value type="java.lang.Boolean">false</value></entry> </map> </property> </bean>
it seems that the only options available are those listed in the Jaxb2Marshaller Javadoc:
public void setMarshallerProperties(Map<String, ?> properties) { this.marshallerProperties = properties; }
2) I also tried setting up unmarshaller in code:
try { jc = JAXBContext.newInstance("com.mycompany.mypkg"); Unmarshaller u = jc.createUnmarshaller(); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(false);//Tried this option. DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(xmlFile.toFile()); u.unmarshal(new DOMSource(doc)); return (Foo)u.unmarshal(new StreamSource(xmlFile.toFile())); } catch (ParserConfigurationException | SAXException | IOException | JAXBException e) { LOGGER.error("Erreur Unmarshalling CPL"); }
3) Different form with SAXParser:
try { jc = JAXBContext.newInstance("com.mycompany.mypkg"); Unmarshaller um = jc.createUnmarshaller(); final SAXParserFactory sax = SAXParserFactory.newInstance(); sax.setNamespaceAware(false); final XMLReader reader = sax.newSAXParser().getXMLReader(); final Source er = new SAXSource(reader, new InputSource(new FileReader(xmlFile.toFile()))); return (Foo)um.unmarshal(er); }catch(...) {[...]}
It works! . However, I would prefer the Unmarshaller auto-amplifier to be able to use this ugly conf every time without having to.