Discussion:
Unmarshalling Error: prefix xsd is not bound to a namespace
Shyamranny
2011-07-18 08:00:37 UTC
Permalink
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-tp4598539p4598539.html
Sent from the cxf-user mailing list archive at Nabble.com.
Aki Yoshida
2011-07-20 14:19:27 UTC
Permalink
Hi,
okay, you are saying that your previous non-soap service
implementation didn't complain about the missing namespace declaration
but your current cxf based implementation complains about the missing
xsd namespace declaration needed to decode the type value. This
happens because the generated code is xml-schema-aware and expects a
valid type in the xsi attribute value if given.

First of all, it's not a good idea to make your SOAP service
implementation ignore the missing declaration, but there is a
possibility to let the missing declarations ignored by using a jaxws
provider based service. In this case, you just have a plain XML based
interface in your service implementaiton using
javax.xml.transform.Source and you can parse the XML document as you
like.

You can look at the jaxws_dispatch_provider sample in the sample distribution.

But as I said, you should really be fixing the clients by making them
either not sending the xsi attributes or including the xsd namespace
declaration instead of adding this workaround in the service
implementation to accept those invalid messages.

regards, aki
Post by Shyamranny
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-tp4598539p4598539.html
Sent from the cxf-user mailing list archive at Nabble.com.
Shyam
2011-07-21 05:20:25 UTC
Permalink
Hi Aki Yoshida,

Thank you for your immediate response. I will have a look t the sample application (our client is not aware of the new implementation, so we cannot ask client to change there soap xml).

Thanks and regards,
Shyam S
Post by Aki Yoshida
Hi,
okay, you are saying that your previous non-soap service
implementation didn't complain about the missing namespace declaration
but your current cxf based implementation complains about the missing
xsd namespace declaration needed to decode the type value. This
happens because the generated code is xml-schema-aware and expects a
valid type in the xsi attribute value if given.
First of all, it's not a good idea to make your SOAP service
implementation ignore the missing declaration, but there is a
possibility to let the missing declarations ignored by using a jaxws
provider based service. In this case, you just have a plain XML based
interface in your service implementaiton using
javax.xml.transform.Source and you can parse the XML document as you
like.
You can look at the jaxws_dispatch_provider sample in the sample distribution.
But as I said, you should really be fixing the clients by making them
either not sending the xsi attributes or including the xsd namespace
declaration instead of adding this workaround in the service
implementation to accept those invalid messages.
regards, aki
Post by Shyamranny
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-tp4598539p4598539.html
Sent from the cxf-user mailing list archive at Nabble.com.
Daniel Kulp
2011-07-21 20:30:57 UTC
Permalink
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
Post by Shyamranny
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
--
http://cxf.547215.n5.nabble.com/Unmarshalling-Error-prefix-xsd-is-not-bound
-to-a-namespace-tp4598539p4598539.html Sent from the cxf-user mailing list
archive at Nabble.com.
--
Daniel Kulp
dkulp-1oDqGaOF3Lkdnm+***@public.gmane.org
http://dankulp.com/blog
Talend - http://www.talend.com
Shyamranny
2011-07-22 05:59:08 UTC
Permalink
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
Post by Daniel Kulp
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
Post by Shyamranny
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
--
http://cxf.547215.n5.nabble.com/Unmarshalling-Error-prefix-xsd-is-not-bound
-to-a-namespace-tp4598539p4598539.html Sent from the cxf-user mailing list
archive at Nabble.com.
--
Daniel Kulp
[hidden email]
http://dankulp.com/blog
Talend - http://www.talend.com
http://cxf.547215.n5.nabble.com/Unmarshalling-Error-prefix-xsd-is-not-bound-to-a-namespace-tp4598539p4620871.html
To unsubscribe from Unmarshalling Error: prefix xsd is not bound to a namespace, click here.
--
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.
Sergey Beryozkin
2011-07-22 11:04:14 UTC
Permalink
You are on the right path, but realistically you'll need to spend more
time on checking in the debugger what is happening.
Consider extending org.apache.cxf.staxutils.DepthXMLStreamReader
instead, and may be you can simplify things by blocking this attribute,
otherwise you may also need to overwrite the methods dealing with
NamespaceContext.
Also overwrite DepthXMLStreamReader.getReader() and return 'this';

Not sure, may be we can enhance InTransformReader to be able to block
attributes too,

Hope this helps
Sergey
Post by Shyamranny
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
Post by Daniel Kulp
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
Post by Shyamranny
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
--
http://cxf.547215.n5.nabble.com/Unmarshalling-Error-prefix-xsd-is-not-bound
-to-a-namespace-tp4598539p4598539.html Sent from the cxf-user mailing list
archive at Nabble.com.
--
Daniel Kulp
[hidden email]
http://dankulp.com/blog
Talend - http://www.talend.com
http://cxf.547215.n5.nabble.com/Unmarshalling-Error-prefix-xsd-is-not-bound-to-a-namespace-tp4598539p4620871.html
To unsubscribe from Unmarshalling Error: prefix xsd is not bound to a namespace, click here.
--
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
2011-07-22 13:38:58 UTC
Permalink
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
Post by Shyamranny
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);
Post by Shyamranny
ShaymStreamReaderDelegate ss = new
ShaymStreamReaderDelegate(xr);
Post by Shyamranny
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
Post by Daniel Kulp
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
Post by Shyamranny
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
--
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
dkulp-1oDqGaOF3Lkdnm+***@public.gmane.org
http://dankulp.com/blog
Talend - http://www.talend.com
Shyam
2011-07-26 06:56:53 UTC
Permalink
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 Kulp
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
Post by Shyamranny
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);
Post by Shyamranny
ShaymStreamReaderDelegate ss = new
ShaymStreamReaderDelegate(xr);
Post by Shyamranny
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
Post by Daniel Kulp
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
Post by Shyamranny
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
--
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
Loading...