I wrote my own CastorUnmarshaller based your code. Unfortunately, all the relevent methods in the CastorMarshaller class are final (!), so extending it is not an option. What about include the source code in the download?
In essence, I just strip all the attributes from the reply node. This wouldn't work for everybody though. Probably better to selectively remove the namespaced atttributes only.
Code:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.dom.DOMResult;
import org.exolab.castor.mapping.Mapping;
import org.exolab.castor.mapping.MappingException;
import org.exolab.castor.xml.MarshalException;
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.UnmarshalHandler;
import org.exolab.castor.xml.Unmarshaller;
import org.exolab.castor.xml.ValidationException;
import org.exolab.castor.xml.XMLContext;
import org.exolab.castor.xml.XMLException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.oxm.AbstractMarshaller;
import org.springframework.oxm.XmlMappingException;
import org.springframework.oxm.castor.CastorSystemException;
import org.springframework.oxm.castor.CastorUnmarshallingFailureException;
import org.springframework.oxm.castor.CastorUtils;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.ext.LexicalHandler;
public class CastorUnmarshaller extends AbstractMarshaller implements InitializingBean {
public CastorUnmarshaller() {}
public CastorUnmarshaller(Resource mappingResource) {
this.mappingLocation = mappingResource;
}
@Override
protected void marshalXmlEventWriter(Object arg0, XMLEventWriter arg1) throws XmlMappingException {
}
@Override
protected void marshalXmlStreamWriter(Object arg0, XMLStreamWriter arg1) throws XmlMappingException {
}
@Override
protected Object unmarshalXmlEventReader(XMLEventReader arg0) throws XmlMappingException {
return null;
}
@Override
protected Object unmarshalXmlStreamReader(XMLStreamReader arg0) throws XmlMappingException {
return null;
}
@Override
public boolean supports(Class arg0) {
return true;
}
void stripAtts(Node node) {
NamedNodeMap map = node.getAttributes();
if (map != null) {
Element el = (Element) node;
for (int i = 0; i < map.getLength(); i++) {
el.removeAttribute(map.item(i).getNodeName());
}
}
NodeList list = node.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
stripAtts(list.item(i));
}
}
@Override
protected Object unmarshalDomNode(Node node) throws XmlMappingException {
stripAtts(node);
Object result = null;
try {
Mapping mapping = XMLContext.createMapping();
mapping.loadMapping(this.mappingLocation.getURL());
XMLContext context = new XMLContext();
context.addMapping(mapping);
Unmarshaller castorUnmarshaller = context.createUnmarshaller();
castorUnmarshaller.setClass(Response.class);
result = castorUnmarshaller.unmarshal(node);
} catch (MarshalException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ValidationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MappingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
public static final String DEFAULT_ENCODING = "UTF-8";
private Resource mappingLocation;
private String encoding;
private Mapping mapping;
private Unmarshaller unmarshaller;
private Class clazz;
private String getEncoding() {
return (encoding != null) ? encoding : DEFAULT_ENCODING;
}
public void setEncoding(String encoding) {
this.encoding = encoding;
}
public void setMapping(Mapping mapping) {
this.mapping = mapping;
}
public void setMappingLocation(Resource mappingLocation) {
this.mappingLocation = mappingLocation;
}
public final void afterPropertiesSet() throws Exception {
if ((mappingLocation != null) && (mapping == null)) {
Mapping castorMapping = new Mapping();
InputStream inputStream = mappingLocation.getInputStream();
try {
castorMapping.loadMapping(new InputSource(inputStream));
this.mapping = castorMapping;
}
finally {
inputStream.close();
}
}
if (mapping != null) {
try {
unmarshaller = new Unmarshaller(mapping);
}
catch (MappingException ex) {
throw new CastorSystemException("Could not load Castor mapping: " + ex.getMessage(), ex);
}
}
else {
unmarshaller = new Unmarshaller(clazz);
}
}
/**
* Converts the given <code>CastorException</code> to an appropriate exception from the
* <code>org.springframework.oxm</code> hierarchy.
* <p/>
* The default implementation delegates to <code>CastorUtils</code>. Can be overridden in subclasses.
* <p/>
* A boolean flag is used to indicate whether this exception occurs during marshalling or unmarshalling, since
* Castor itself does not make this distinction in its exception hierarchy.
*
* @param ex Castor <code>XMLException</code> that occured
* @param marshalling indicates whether the exception occurs during marshalling (<code>true</code>), or
* unmarshalling (<code>false</code>)
* @return the corresponding <code>XmlMappingException</code>
* @see CastorUtils#convertXmlException
*/
public XmlMappingException convertCastorException(XMLException ex, boolean marshalling) {
return CastorUtils.convertXmlException(ex, marshalling);
}
private void marshal(Object graph, Marshaller marshaller) {
try {
if (mapping != null) {
marshaller.setMapping(mapping);
}
marshaller.marshal(graph);
}
catch (MappingException ex) {
throw new CastorSystemException("Could not load Castor mapping", ex);
}
catch (XMLException ex) {
throw convertCastorException(ex, true);
}
}
protected void marshalDomNode(Object graph, Node node) throws XmlMappingException {
Marshaller marshaller = new Marshaller(node);
marshal(graph, marshaller);
}
protected void marshalOutputStream(Object graph, OutputStream outputStream)
throws XmlMappingException, IOException {
OutputStreamWriter writer = new OutputStreamWriter(outputStream, getEncoding());
marshalWriter(graph, writer);
}
protected void marshalSaxHandlers(Object graph, ContentHandler contentHandler, LexicalHandler lexicalHandler)
throws XmlMappingException {
try {
Marshaller marshaller = new Marshaller(contentHandler);
marshal(graph, marshaller);
}
catch (IOException ex) {
throw new CastorSystemException("Could not construct Castor ContentHandler Marshaller", ex);
}
}
protected void marshalWriter(Object graph, Writer writer) throws XmlMappingException, IOException {
Marshaller marshaller = new Marshaller(writer);
marshal(graph, marshaller);
}
@Override
protected void marshalDomResult(Object graph, DOMResult domResult) throws XmlMappingException {
super.marshalDomResult(graph, domResult);
}
protected Object unmarshalSaxReader(XMLReader xmlReader, InputSource inputSource)
throws XmlMappingException, IOException {
UnmarshalHandler unmarshalHandler = unmarshaller.createHandler();
try {
unmarshalHandler.startPrefixMapping("xsi", "http://www.w3.org/2001/XMLSchema-instance");
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
ContentHandler contentHandler = Unmarshaller.getContentHandler(unmarshalHandler);
xmlReader.setContentHandler(contentHandler);
xmlReader.parse(inputSource);
return unmarshalHandler.getObject();
}
catch (SAXException ex) {
throw new CastorUnmarshallingFailureException(ex);
}
}
protected Object unmarshalInputStream(InputStream inputStream) throws XmlMappingException, IOException {
try {
return unmarshaller.unmarshal(new InputSource(inputStream));
}
catch (XMLException ex) {
throw convertCastorException(ex, false);
}
}
protected Object unmarshalReader(Reader reader) throws XmlMappingException, IOException {
try {
return unmarshaller.unmarshal(new InputSource(reader));
}
catch (XMLException ex) {
throw convertCastorException(ex, false);
}
}
public void setTargetClass(Class clazz) {
this.clazz = clazz;
}
}