Hi Daan,
Solved by creating the following class. It may look not pretty, but worked for me.
public class MediatorInInterceptor extends AbstractPhaseInterceptor<SoapMessage>{
public MediatorInInterceptor() {
super(Phase.POST_STREAM);
addBefore(StaxInInterceptor.class.getName());
}
public void handleMessage(SoapMessage message) throws Fault {
try {
InputStream is = message.getContent(InputStream.class);
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
Document doc = docBuilder.parse(is);
String xml = xmlToString(doc);
String prefix = getPrifixOfType(xml);
if(null != prefix && prefix.length() > 0 && (! isNamesoaceDeclared(xml, prefix))){
Element root = doc.getDocumentElement();
root.setAttribute("xmlns:" + prefix, "http://www.w3.org/2001/XMLSchema/");
xml = xmlToString(doc);
ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes());
message.setContent(InputStream.class, bais);
}
} catch (Throwable e) {
}
}
private boolean isNamesoaceDeclared(String xml, String prefix) {
return xml.contains("xmlns:" + prefix);
}
private String getPrifixOfType(String xml) {
Pattern p = Pattern.compile("(:type=)(.*?)(>)");
Matcher m = p.matcher(xml);
if(m.find()){
String match = m.group().replace(":type=", "").replaceAll("\"", "");
return match.substring(0, match.indexOf(":"));
}
return null;
}
private String xmlToString(Node node) {
try {
Source source = new DOMSource(node);
StringWriter stringWriter = new StringWriter();
Result result = new StreamResult(stringWriter);
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
transformer.transform(source, result);
return stringWriter.getBuffer().toString();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
return null;
}
}
Thanks and regards,
Shyam S
Post by Daniel KulpAs Sergey mentioned, there are other methods on the StreamReaderDelegate that
you may need to override instead. There are several ways that can be used to
map a prefix to a namespace. I don't know which method JAXB uses when
processing the xsi:type. The NamespaceContext methods might be the methods
you need to override as well. Without debugging into JAXB, I'm really not
sure.
Dan
Post by ShyamrannyHi Dan,
Thank you for your reply. I have created a 'MediatorInInterceptor' extending
'AbstractPhaseInterceptor<SoapMessage>'. Following is the class
definition.
public class MediatorInInterceptor extends
AbstractPhaseInterceptor<SoapMessage>{
public MediatorInInterceptor() {
super(Phase.POST_STREAM);
addAfter(StaxInInterceptor.class.getName());
}
public void handleMessage(SoapMessage message) throws Fault {
try {
XMLStreamReader xr =
message.getContent(XMLStreamReader.class);
Post by ShyamrannyShaymStreamReaderDelegate ss = new
ShaymStreamReaderDelegate(xr);
Post by Shyamrannymessage.setContent(XMLStreamReader.class, ss);
} catch (Throwable e) {
}
}
}
The 'ShaymStreamReaderDelegate' is a class that extends
'StreamReaderDelegate'. Following is the class definition.
public class ShaymStreamReaderDelegate extends StreamReaderDelegate {
public ShaymStreamReaderDelegate(XMLStreamReader reader){
super(reader);
}
@Override
public String getNamespaceURI(String prefix) {
if(prefix.equalsIgnoreCase("xsd")){
return "http://www.w3.org/2001/XMLSchema/";
}
return super.getNamespaceURI(prefix);
}
}
I have added the 'MediatorInInterceptor' in the jaxws in interceptors collection.
But when I run this I am getting the same exception. Also beak point places
inside 'getNamespaceURI' did not hit.
Thanks and regards,
Shyam S
Post by Daniel KulpYou could TRY writing a CXF interceptor that would live after the
StaxInInterceptor that would grab the XmlStreamReader, wrapper it with a
StreamReaderDelegate that overrides the various namespace lookup methods
(like getNamespaceURI(String prefix)) and set that back into the
message. That may allow you to "pretend" those prefixes are there.
Dan
Post by ShyamrannyHi,
I have upgraded my web service and now the new webservice uses CXF.
When I send my old soap message to the new CXF webservice, i am
getting the following response.
'Unmarshalling Error: prefix xsd is not bound to a namespace'.
In my soap request, I have the following element.
'<A700129Naam xsi:type="xsd:string">Shyam</A700129Naam>' Here I use the
prefix 'xsd' and if I add this prefix in the xmlns, this soap will
go well. But our client will not change there soap request. They
need to send the old soap request.
How can I solve this issue? Can I add namespace and prefix in the
spring configuration file? I have tried a lot like XMLFilterImpl,
AbstractInDatabindingInterceptor, NamespacePrefixMapper etc. But not worked.
Thanks and regards,
Shyam S
--
http://cxf.547215.n5.nabble.com/Unmarshalling-Error-prefix-xsd-is-not-bound
-to-a-namespace-tp4598539p4621888.html Sent from the cxf-user mailing list
archive at Nabble.com.
--
Daniel Kulp
http://dankulp.com/blog
Talend - http://www.talend.com