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
On 22-Jul-2011, at 7:08 PM, Daniel Kulp wrote:
>
> As 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
>
>
>
> On Thursday, July 21, 2011 10:59:08 PM Shyamranny wrote:
>> Hi 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);
>> ShaymStreamReaderDelegate ss = new
> ShaymStreamReaderDelegate(xr);
>> message.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
>>
>> On 22-Jul-2011, at 2:01 AM, Daniel Kulp [via CXF] wrote:
>>> You 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
>>>
>>> On Monday, July 18, 2011 1:00:37 AM Shyamranny wrote:
>>>> Hi,
>>>>
>>>> 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
>>
>> --
>> View this message in context:
>> 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
> [email protected]
> http://dankulp.com/blog
> Talend - http://www.talend.com