CXF Client Side Duplication of targetnamespace - java

I am hosting a webservice and a webapp on the same server, generated from wsdl2java. I can contact the service just fine through SoapUI and it returns a single namespace declaration when posted to the live server, but when I am working locally and use SoapUI it generates two instances of xlmns="" instead of a single one in my xml. I have copied below an example xml file:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body>
<SendResponse xmlns="http://myendpoint.org/service" xmlns:ns2="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<Receipt>
<MyReceipt xmlns:ns3="http://myendpoint.org/service" xmlns="" xmlns="" xmlns:ns6="http://myapp.myserver.net/myservicegroup/myservice/V01" receiptVersion="V01">
<ReceiptHeader>
<ReceiptTimestamp>2010-04-13T08:27:03.036-04:00</ReceiptTimestamp>
</ReceiptHeader>
<TransmissionReceipt>
<TransmissionID>testuser</TransmissionID>
<TransmissionTimestamp>2010-04-13T08:27:03.036-04:00</TransmissionTimestamp>
</TransmissionReceipt>
</MyReceipt></Receipt></SendResponse></soap:Body></soap:Envelope>
So when it unmarshalls, it fails badly when I use my webapp as a webservice client. Why is CXF adding a second namespace? I watched the debug all the way through until the return and it looked 100% perfect on the webservice side, no duplicate name space at all. It does not happen until the return of the xml to the client side.

In XML, attributes are unique to each element, so if this occurs then it is probably a bug and you should report it as such. I've worked with CXF before and it's a great library, but it's unfortunately not perfect. I had to mess around with various versions, upgrading to an unstable one to get around the bugs I encountered.
W3C XML Spec
An attribute name MUST NOT appear more than once in the same start-tag or empty-element tag.

Related

Apache CXF WSDL Resolution

Using Apache CXF 2.7.7 if I publish a simple "HelloWorld" JAX-WS service and attempt to resolve the WSDL URL in a web browser using: "localhost:8080/service/HelloWorld?wsdl" the WSDL loads in the browser and everything looks great.
If I then add the below annotation which changes the SOAP Binding to 1.2 the WSDL resolution still works but the WSDL doesn't load in the browser, instead a download dialog is shown and the name of the WSDL is missing the file name extension in the download dialog (which is probably why it isn't loading in the browser).
javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING
The same behavior appears with the SOAP12HTTP_MTOM_BINDING
#javax.xml.ws.BindingType (value=javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_MTOM_BINDING)
Functionally everything works fine even with the BindingType annotation defined so this is just a minor annoyance but I'm wondering how I can get the correct WSDL resolution behavior when the default SOAP 1.1 binding is in use.
I posted this issue on the Apache CXF JIRA and it was acknowledged as a defect. It has been fixed and will be included with the Apache CXF 2.7.8 release.
https://issues.apache.org/jira/browse/CXF-5334

SOAPFactory creating 'null' value for 'soap' namespace in addressing header tag

From within a J2EE application running in JBoss4.2.3 we are creating a SOAPConnection to invoke a 3rd party's web service. Inside the SOAP Header we have to set the Addressing To and Action tags, with 'mustUnderstand' set to '1'. This 'mustUnderstand' attribute is in the http://www.w3.org/2003/05/soap-envelope namespace. We create this by calling:
SOAPFactory#createName("mustUnderstand", "soap", "http://www.w3.org/2003/05/soap-envelope");
This comes out correctly when we include saaj.jar and saaj-impl.jar in our WEB-INF/lib folder. If I take these out, the namespace comes out null as: xmlns:soap='null' instead of xmlns:soap="http://www.w3.org/2003/05/soap-envelope". Here's the entire bad tag:
<wsa:To xmlns:wsa='http://schemas.xmlsoap.org/ws/2004/08/addressing' xmlns:soap='null' soap:mustUnderstand='1'>http://domain/web-service.url</wsa:To>.
But if we have those 2 jar files deployed with the app, our own hosted web-services fail when creating Faults (due to a class-cast exception:
javax.xml.soap.SOAPException: java.lang.ClassCastException: com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl)
Our J2EE app is a JBossWS web-service that invokes 3rd-party web-services itself. There is an apparent conflict with the jar files.
Any ideas on how to get the http://www.w3.org/2003/05/soap-envelope namespace to be written out in the generated SOAP tag?
I ended up using the API directly to call SOAPHeaderElement#mustUnderstand(true). This looks to have solved this issue since another namespace declaration isn't needed (it uses the soap-env namespace declaration from teh envelope itself.
I still have another issue (JBoss wants to send a chunked HTTP request, which the 3rd party web-service isn't liking, but I haven't looked far enough into that one yet)

Accessing SOAP web service with incorrect wsdl

Background:
I need to consume an existing web service (SOAP over http) that has a couple of issues:
1) The wsdl on the server doesn't even resemble the web service as described in their documentation, which includes a completely different wsdl file
2) The wsdl file provided with their documentation seems to come close to describing the web service on the server, but when I generated java client code using cxf and used it to access the web service, cxf throws exceptions like the following
javax.xml.bind.UnmarshalException: unexpected element (uri:"http://us-labs.companyxyz.com/", local:"searchResponse"). Expected elements are <{http://companyxyz.com/xyz-xml/2.0/}searchResponse>
... 33 more
I'm no SOAP expert, but assuming this means the namespaces in their response don't match those defined in the wsdl.
Since my application is written in java, I was able to connect and get a response using commons http client and a handcrafted SOAP request, so worst case I can fall back to that and parse the response to get what I need.
My questions:
Did I interpret the exception correctly?
If no: any suggestions on how I can debug this?
If yes: can anyone suggest better alternatives to handcrafting http requests and parsing xml by hand? (Getting correct wsdl is, unfortunately, not an option)
Thanks in advance.
Most likely. The response is using the namespace "http://us-labs.companyxyz.com/", but in the WSDL, the same element is declared with namespace "http://companyxyz.com/xyz-xml/2.0/".
I'm not familiar with CXF, but other SOAP frameworks usually offer some kind of logging capabilities. It would probably help you if the SOAP requests and responses are logged somewhere for more specific analysis.
Why is it not an option to get a correct WSDL? If you really are able to "handcraft" correct SOAP requests and expect to be able to "handparse" the responses, you should be able to write the WSDL yourself as well. Of course, the WSDL should be provided to you by the service operator, but if you mean that noone is able to provide you with a correct WSDL, I would consider writing it myself instead of creating and parsing the SOAP messages manually.
I think you interpreted the exception correctly - the namespace is different than expected.
It is also not really unexpected. it is a fact of life that vendor supplied wsdls are not always correct. We actually write our own WSDLs and XSDs for vendor applications for just that reason.
You can use your own WSDL even run-time. There are some SO questions on that, here and here.
You could also have a look here. I haven't tried it, but it could work.
We actually extend the generated service and create a port supplying a WSDL located on the classpath using the JaxWS Service constructor. That works fine for us.
We debug CXF by dumping the incoming and outgoing messages. There seem to be quite a lot of methods to do just that. We use either a proxy between de web service and our client, or recently a cxf.xml file somewhere. Using a -D flag we temprarily configure this.
-Dcxf.config.file=/home/me/cxf-debug.xml
and cxf-debug.xml contains something like:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<cxf:bus>
<cxf:features>
<cxf:logging/>
</cxf:features>
</cxf:bus>
</beans>
http://cxf.apache.org/docs/debugging-and-logging.html
Both responses suggested the same basic approach, which turned out to be the correct one.
I fixed the provided wsdl to make it match the web service, and I was able to use cxf, which saved me a lot of hand coding.
The main problem with their wsdl was in fact a namespace issue. The essence of the problem was as follows: their wsdl defined two namespaces, both of which have a "searchResponse" element.
{http://us-labs.companyxyz.com/}searchResponse
was defined in the wsdl to contain 0 or more
{http://companyxyz.com/xyz-xml/2.0/}searchResponse
But in their response the nested searchResponse wasn't qualified by {http://companyxyz.com/xyz-xml/2.0/} so cxf interpreted it as a {http://us-labs.companyxyz.com/}searchResponse
I fixed it by introducing a new type.
Thanks to both responders.

Consuming Java Web Service from .NET

I have a web service written in Java now I want to consume that web service in the .NET world. I use the WSDL to add a proxy class to my .NET application but when I invoke the Java web service method the response is always null. Anyone familiar with this issue?
UPDATE 1:
Another thing I noted is that I opened one of the svcinfo files and found the following code:
<endpoint normalizedDigest="<?xml version="1.0" encoding="utf-16"?><Data address="http://fff.mywebserive/somewebservie" binding="basicHttpBinding" bindingConfiguration="DOC_TOI_Binding" contract="ServiceReference1.DOC_TOI_PortType" name="DOC_TOI_Port" />" digest="<?xml version="1.0" encoding="utf-16"?><Data
This does not look right to me!
UPDATE 2: Solution (Kind of)
The problem was that the response had a different namespace than used by the client proxy class. This way the object was never deserialized correctly. Once, I changed the namespace to match the response namespace it worked fine. But now if I update the web service reference I will again get the same issue as the namespace will be updated. What is a good way to solve this problem? The only solution I can think of is to ask the creator of the webservice to use the correct namespace.
Using .Net, we can add the java web service in our application using Service Referrence or Web Service Referrence.
Service Reference - This is a dedicated way of calling Microsoft WCF Web Services 3.5 and higher.
Web Service Reference - Way of referencing Non Microsoft Web Service and lower version of Microsoft webservice such as 2.0
We can also use Service reference in non Microsoft web service, we just need to modify some configuration in app.config such as Security Configurations()
Now, when Invoking the web service request method it always ends up with the NULL object response.
(This is caused by the discrepancy between the proxy namespace expected response and the actual xml namespace webservice response )
Sample:
Proxy Code
[return: System.Xml.Serialization.XmlElementAttribute("GetResponse ", Namespace = "http://AJ_TUASON.COM ")]
Public GetResponse Get()
{}
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://AJ_TUASON.COM")]
public partial class GetResponse
{}
Actual XML Namespace Response
webservice:GetResponse xmlns:"http://AJTUASON.COM"
To resolve this issue, install fiddler2. This will helps you track and confirm that the web services are working fine.
Then, copy the actual namespace in the XML response from web service.
Paste the actual xml namespace response in proxy class of .NET:
Sample:
[return: System.Xml.Serialization.XmlElementAttribute("GetResponse ", Namespace = "http://AJTUASON.COM ")]
Public GetResponse Get()
{}
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://AJTUASON.COM")]
public partial class GetResponse
{}
This will resolve the Null issue.
Note: Do not always rely on the tool that generates proxy class. Tools can surely translate but doing analysis is another thing - AJ
It suggests to me that either your WSDL or your client is incorrect. The client should not be able to tell from the WSDL what language it's implemented in. Check your namespaces.
SOAP UI is a very nice tool for testing SOAP services. I'd recommend it for sorting out this issue.
Looks to me like something tried to escape that snippet. You don't want > you want >
You need to make sure that the service and the client are using the same namespace. Communication is paramount here.

How do I interpret a WSDL with references to a namespace java: on a non-java client?

I'm trying to integrate against a SOAP web service, running on Apache Axis. The WSDL specifies a namespace with a URI, that looks like:
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:stns="java:dk.tdc.serviceproviderweb.datatypes"
elementFormDefault="qualified"
attributeFormDefault="qualified"
targetNamespace="java:dk.tdc.serviceproviderweb.datatypes">
On the client-side, I'm using PHP, so the namespace xmlns:stns is meaningless. I have some Java class files (and their sources), that seems to correspond to this namespace. How do I handle this in a meaningful way?
OK. It seems that I got confused by the fact that my client library had a bug, which made it choke on the wsdl. I switched from NuSOAP to php5's native soap library, and things works now.
Your snippet is the beginning of an XML schema that defines the contents of the "java:dk.tdc.serviceproviderweb.datatypes" namespace. (The targetNamespace attribute indicates this).
So it shouldn't matter if you're handling this with java or PHP on the client side,
as long as the rest of this schema is valid.

Categories

Resources