WSDL abstract vs concrete messages - java

I am learning about WSDL from online documentation and came across definitions about abstract message and concrete message:
Message definitions are always considered to be an abstract definition
of the message content. A message binding describes how the abstract
content is mapped into a concrete format.
However, in some cases, the abstract definition may match the concrete representation very closely or exactly for one or more bindings, so those binding(s) will supply
little or no mapping information.
However, another binding of the same message definition may require extensive mapping information. For this reason, it is not until the binding is inspected that one can
determine "how abstract" the message really is.
Please help me in understanding what the above definition means? Can you please provide some examples for the same.
When we call a message as Abstract and when it will be called as concrete in WSDL terms?

The message part is considered abstract as it does not really define how the content formatting of the actual SOAP message will look like. Please have a look at this IBM article which does a great job on presenting the differences between the available binding styles in WSDL.
Taking the example from this article where the WSDL contract should define a method like public void myMethod(int x, float y); you can declare something like that in the WSDL contract:
<message name="myMethodRequest">
<part name="x" type="xsd:int"/>
<part name="y" type="xsd:float"/>
</message>
<message name="empty"/>
<portType name="PT">
<operation name="myMethod">
<input message="myMethodRequest"/>
<output message="empty"/>
</operation>
</portType>
<binding .../>
Here you just declare the expected elements of a message but you don't really define here how the actual SOAP message matching this definition looks like. This happens in the binding section.
WSDL offers here RPC/encoded ...
<soap:envelope>
<soap:body>
<myMethod>
<x xsi:type="xsd:int">5</x>
<y xsi:type="xsd:float">5.0</y>
</myMethod>
</soap:body>
</soap:envelope>
... RPC/literal ...
<soap:envelope>
<soap:body>
<myMethod>
<x>5</x>
<y>5.0</y>
</myMethod>
</soap:body>
</soap:envelope>
... and Document/literal
<soap:envelope>
<soap:body>
<xElement>5</xElement>
<yElement>5.0</yElement>
</soap:body>
</soap:envelope>
Document/literal is actually not complete here as you furthermore create own types for xsd:int and xsd:float and use this types instead of these types as your message type:
<types>
<schema>
<element name="xElement" type="xsd:int"/>
<element name="yElement" type="xsd:float"/>
</schema>
</types>
<message name="myMethodRequest">
<part name="x" element="xElement"/>
<part name="y" element="yElement"/>
</message>
<message name="empty"/>
<!-- same port type -->
<portType name="PT">
...
<binding ... />
Every method has its strength and its weaknesses - please have a look on the IBM article for further information therefore. Due to the limitations and weaknesses RPC/encoded, RPC/literal and document/literal bare are not used that often - instead a modification of document/literal is used - document/literal wrapped. Here the advantages of all styles are thrown into one single style - which has its further limits of only allowing one <part .../> element for a message:
<types>
<schema>
<element name="myMethod">
<complexType>
<sequence>
<element name="x" type="xsd:int"/>
<element name="y" type="xsd:float"/>
</sequence>
</complexType>
</element>
<element name="myMethodResponse">
<complexType/>
</element>
</schema>
</types>
<message name="myMethodRequest">
<part name="parameters" element="myMethod"/>
</message>
<message name="empty">
<part name="parameters" element="myMethodResponse"/>
</message>
<!-- again same port type -->
<binding ... />
This results in a SOAP message like this:
<soap:envelope>
<soap:body>
<myMethod>
<x>5</x>
<y>5.0</y>
</myMethod>
</soap:body>
</soap:envelope>
However, document/literal wrapped is not really part of the WSDL:
In document/literal style of messaging, there exists a pattern which
is known as wrapped-document/literal. This is just a pattern, and is
not a part of WSDL specification. This pattern has a mention in JSR
224 (JAX-WS: Java API for XML based web services). (Source)
Hope this also answers somehow your other questions: 1, 2
Furthermore, the actual transportation may happen on different protocols like HTTP, JMS, SMTP, ..., as already explained by #Namphibian and #JqueryLearner. This happens within the binding section where you define which protocol and binding style (RPC or document) should be used for which operations:
<binding type="glossaryTerms" name="b1">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" />
<operation>
<soap:operation soapAction="http://example.com/getTerm"/>
<input><soap:body use="literal"/></input>
<output><soap:body use="literal"/></output>
</operation>
</binding>
HTH

Abstract WSDL contains messages without the transport protocol
Concrete WSDl is abstract WSDl plus transport protocol
Transport protocol may be JMS or HTTP

Related

How to annotate web service parameters with constraints in java?

I have a GUI application that creates a bunch of XML documents using jdom and these documents conform to their respective schemas. It also has a WSDL creator class (which follows the standard schema provided by W3C) that creates a Services.wsdl. In this WSDL there are 'n' number of service descriptions with their respective entities(port, binding, type and message elements). The parameters of these web services have specific constraints associated with them.
Question 1: How to annotate service parameters with their specific constraints in the WSDL?
Question 2: Should I be using a custom SLAParameter extended from the WSLA Language by IBM or the WS-Policy language to annotate these parameters with their associated constraints?
XML:
<wsdl:message name="request">
<part name="param1" type="xsd:string"/>
<part name="param2" type="xsd:int"/>
</wsdl:message name="response"/>
<wsdl:message name="response"/>
...
<wsdl:operation name="myMethod" parameterOrder="param1, param2">
<input name="input" message="request"/>
<output name="output" message="response"/>
</wsdl:operation>
Java:
void myMethod(String param1, int param2) ...
P.S. The above snippet's source. WSLA and WS-Policy both complement WSDL in their own ways.

jax-ws :: wsimport and Apache CXF wsdl2java fail on a "normative" W3C WSDL specification example

I am trying to get wsimport or Apache CXF wsdl2java generate stubs for "Example 1" of the W3C WSDL 1.1 spec. (also copied verbatim at the end of the post).
The example appears to have a small typo, but even after replacing:
binding="tns:StockQuoteBinding
with
binding="tns:StockQuoteSoapBinding
both wsimport and wsdl2java still fail.
I've tried, the command line version (JAX-WS RI 2.2.4) and the Ant Task version (JAX-WS RI 2.2.8) of wsimport as well as the command line version of Apache CXF wsdl2java (2.7.6). They all seem to fail for the same reason more or less:
$ wsimport -version
JAX-WS RI 2.2.4-b01
$ wsimport -d src-auto-wsimport/ -p foo.client -Xnocompile specs/example1.wsdl
parsing WSDL...
[ERROR] Schema descriptor {http://example.com/stockquote.xsd}TradePriceRequest in message part "body" is not defined and could not be bound to Java. Perhaps the schema descriptor {http://example.com/stockquote.xsd}TradePriceRequest is not defined in the schema imported/included in the WSDL. You can either add such imports/includes or run wsimport and provide the schema location using -b switch.
line 31 of file:/home/brutus/jax-ws/wsdl/specs/example1.wsdl
From what I can see, the type it complains about (TradePriceRequest) is properly defined in the schema that's provided inside the WSDL file so I can't see why it fails to find it. (Apache CXF wsdl2java complains about the same type as well in a slightly different message)
Any ideas on what's wrong with this WSDL file?
example 1 WSDL (verbatim from the W3C WSDL 1.1 spec linked above)
NB: you need to change binding="tns:StockQuoteBinding to binding="tns:StockQuoteSoapBinding
<?xml version="1.0"?>
<definitions name="StockQuote"
targetNamespace="http://example.com/stockquote.wsdl"
xmlns:tns="http://example.com/stockquote.wsdl"
xmlns:xsd1="http://example.com/stockquote.xsd"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns="http://schemas.xmlsoap.org/wsdl/">
<types>
<schema targetNamespace="http://example.com/stockquote.xsd"
xmlns="http://www.w3.org/2000/10/XMLSchema">
<element name="TradePriceRequest">
<complexType>
<all>
<element name="tickerSymbol" type="string"/>
</all>
</complexType>
</element>
<element name="TradePrice">
<complexType>
<all>
<element name="price" type="float"/>
</all>
</complexType>
</element>
</schema>
</types>
<message name="GetLastTradePriceInput">
<part name="body" element="xsd1:TradePriceRequest"/>
</message>
<message name="GetLastTradePriceOutput">
<part name="body" element="xsd1:TradePrice"/>
</message>
<portType name="StockQuotePortType">
<operation name="GetLastTradePrice">
<input message="tns:GetLastTradePriceInput"/>
<output message="tns:GetLastTradePriceOutput"/>
</operation>
</portType>
<binding name="StockQuoteSoapBinding" type="tns:StockQuotePortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="GetLastTradePrice">
<soap:operation soapAction="http://example.com/GetLastTradePrice"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="StockQuoteService">
<documentation>My first service</documentation>
<port name="StockQuotePort" binding="tns:StockQuoteBinding">
<soap:address location="http://example.com/stockquote"/>
</port>
</service>
</definitions>

How does webservice application know soap call for a particular method,without using operation name in soap message?

Document/literal WSDL for myMethod
<types>
<schema>
<element name="xElement" type="xsd:int"/>
<element name="yElement" type="xsd:float"/>
</schema>
</types>
<message name="myMethodRequest">
<part name="x" element="xElement"/>
<part name="y" element="yElement"/>
</message>
<message name="empty"/>
<portType name="PT">
<operation name="myMethod">
<input message="myMethodRequest"/>
<output message="empty"/>
</operation>
</portType>
<binding .../>
Document/literal SOAP message for myMethod
<soap:envelope>
<soap:body>
<xElement>5</xElement>
<yElement>5.0</yElement>
</soap:body>
</soap:envelope>
How does web service engine know above soap message for a particular method ?
How server application know which method soap message is calling on?
http://www.ibm.com/developerworks/webservices/library/ws-whichwsdl/ link for reference
Server will identify method based on parameter types and annotated with #Webmethod.
In case of two similar method, server will call last method specified in wsdl.

My jax-ws webservice client returns only empty objects

I have a third party webservice for which I generate a client using wsimport. Each call to the webservice completes successfully, but the response object I get back has all its fields set to null. Monitoring the network I can see that on the wire all of the XML elements in the response message have values in them, so the object should have non-null data in it. Also, a client for the same service generated with old axis1 and called with the same data returns a non-empty response. Any idea what's happening? (In case it makes any difference I'm using MOXy's implementation of JAXB).
Update: I've been able to narrow it down. The wsdl defines object in its own namespace, say http://www.acme.com/ws. The response I get from the service is
<?xml version="1.0" encoding="UTF-8"?>
... SOAP envelope ...
<ns1:opINFOWLResponse xmlns:ns1="http://www.acme.com/ws"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns1:responseINFOWL xsi:type="ns1:responseINFOWL">
<result>6003</result>
<ndserr/>
<transid>61437594</transid>
<descriptionerr>BLAH.</descriptionerr>
</ns1:responseINFOWL>
</ns1:opINFOWLResponse>
... SOAP closing tags ...
and is unmarshalled to a non null OpINFOWLResponse which wraps around a non null responseINFOWL object with all the fields set to null. Just for fun I've tried writing a couple of lines to unmarshal the above snippet (after stripping the SOAP overhead)
JAXBContext ctx = JAXBContext.newInstance(OpINFOWLResponse.class);
Unmarshaller u = ctx.createUnmarshaller();
OpINFOWLResponse o = (OpINFOWLResponse) u.unmarshal(new StringReader(theSnippetAbove));
ResponseINFOWL w = o.getResponseINFOWL();
and I get the same result. If I change the XML above to
<?xml version="1.0" encoding="UTF-8"?>
<ns1:opINFOWLResponse xmlns:ns1="http://www.acme.com/ws"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns1:responseINFOWL xsi:type="ns1:responseINFOWL">
<ns1:result>6003</ns1:result>
<ns1:ndserr/>
<ns1:transid>61437594</ns1:transid>
<ns1:descriptionerr>BLAH.</ns1:descriptionerr>
</ns1:responseINFOWL>
</ns1:opINFOWLResponse>
Everything works fine. Bummer.
Update (again): Same behaviour with both jaxb-RI and Moxy. Still have no idea what's wrong.
Update (Sep. 9): The suggestion below about namespace qualification being wrong is interesting, but I supposed wsimport would get things right. Anyway, this is my package-info.java
#XmlSchema(
namespace = "http://www.acme.com/ws",
elementFormDefault = XmlNsForm.QUALIFIED)
package it.sky.guidaTv.service.remote;
import javax.xml.bind.annotation.XmlSchema;
import javax.xml.bind.annotation.XmlNsForm;
and this is the relevant part of the ResponseINFOWL class
/*
* <p>Java class for responseINFOWL complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType name="responseINFOWL">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="result" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="descriptionerr" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="transid" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="ndserr" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="wallet" type="{http://www.acme.com/ws}t_wallet" minOccurs="0"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "responseINFOWL", propOrder = {
"result", "descriptionerr", "transid", "ndserr", "wallet" })
public class ResponseINFOWL {
#XmlElement(required = true)
protected String result;
#XmlElement(required = true)
protected String descriptionerr;
#XmlElement(required = true)
protected String transid;
protected String ndserr;
protected TWallet wallet;
// getters, setters and all.
}
I've tried playing a bit with the namespaces in package-info but still no joy.
I recently ran into the exact same problem you encountered, and it came down to the fact that the service I was contacting was returning something different from what its WSDL advertised. The service used an old version of Apache Axis (1.4) with behaviour that conflicts with current JAX-WS implementations.
In particular, the namespace on the actual response body contents was NOT what was expected by the client code generated by JAX-WS's wsimport utility. For example, the actual response looked something like this, with the serviceResponse and all its children in namespace "http://foo.com":
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<serviceResponse xmlns="http://foo.com">
<messageReturn>
<messageId>12345</messageId>
<status>Ok</status>
</messageReturn>
</serviceResponse>
</soapenv:Body>
</soapenv:Envelope>
In contrast to what was actually coming back, the client stubs generated by wsimport were expecting something like the response below, with the serviceResponse element in namespace "http://foo.com" and the contained child messageReturn element in the anonymous namespace.
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<n1:serviceResponse xmlns:n1="http://foo.com">
<messageReturn>
<messageId>12345</messageId>
<status>Ok</status>
</messageReturn>
</n1:serviceResponse>
</soapenv:Body>
</soapenv:Envelope>
Since I could not change the service I was consuming, I instead wrote a new WSDL myself that used a wrapped doc-literal binding to explicitly control the expected structure of the response (and request, of course). There is a really good article on WSDL binding types over IBM Developerworks.
The WSDL I created looked something like this:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://foo.com"
xmlns:tns="http://foo.com"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!-- Define the XML types we need to send and receive (used by the message definitions below) -->
<wsdl:types>
<schema targetNamespace="http://foo.com" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<!-- Reusable types -->
<complexType name="ResponseType">
<sequence>
<element name="messageId" nillable="true" type="xsd:string" />
<element name="status" nillable="true" type="xsd:string" />
</sequence>
</complexType>
<complexType name="InputType">
<sequence>
<element name="firstName" nillable="true" type="xsd:string" />
<element name="lastName" nillable="true" type="xsd:string" />
<element name="command" nillable="true" type="xsd:string" />
</sequence>
</complexType>
<!-- Specific input/output elements used in wsdl:message definitions -->
<element name="serviceResponse">
<complexType>
<sequence>
<element name="messageReturn" type="tns:ResponseType" />
</sequence>
</complexType>
</element>
<element name="serviceRequest">
<complexType>
<sequence>
<element name="message" type="tns:InputType" />
</sequence>
</complexType>
</element>
</schema>
</wsdl:types>
<!-- Define the WSDL messages we send/receive (used by the port definition below) -->
<wsdl:message name="serviceResponseMessage">
<wsdl:part name="part1Name" element="tns:serviceResponse" />
</wsdl:message>
<wsdl:message name="serviceRequestMessage">
<wsdl:part name="part1name" element="tns:serviceRequest" />
</wsdl:message>
<!-- Define the WSDL port (used by the binding definition below) -->
<wsdl:portType name="ServicePort">
<wsdl:operation name="serviceOperation">
<wsdl:input message="tns:serviceRequestMessage" />
<wsdl:output message="tns:serviceResponseMessage" />
</wsdl:operation>
</wsdl:portType>
<!-- Define the WSDL binding of the port (used by the service definition below) -->
<wsdl:binding name="ServiceSoapBinding" type="tns:ServicePort">
<wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="serviceOperation">
<wsdlsoap:operation soapAction="" />
<wsdl:input>
<wsdlsoap:body use="literal" />
</wsdl:input>
<wsdl:output>
<wsdlsoap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<!-- Finally, define the actual WSDL service! -->
<wsdl:service name="UserCommandService">
<wsdl:port binding="tns:ServiceSoapBinding" name="ServicePort">
<!-- This address is just a placeholder, since the actual target URL will be specified at runtime -->
<wsdlsoap:address location="http://localhost:8080/blah" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
With the custom WSDL, I was able to use wsimport to generate client stubs that work perfectly with the service. As well, with the wrapped doc-literal approach, I completely control the expected structure and namespace of the request/response, so I can implement multiple namespaces in that XML if necessary.
Enjoy...
Please correct me if I have your use case incorrect.
You can unmarshal:
<?xml version="1.0" encoding="UTF-8"?>
<ns1:opINFOWLResponse xmlns:ns1="http://www.acme.com/ws"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns1:responseINFOWL xsi:type="ns1:responseINFOWL">
<ns1:result>6003</ns1:result>
<ns1:ndserr />
<ns1:transid>61437594</ns1:transid>
<ns1:descriptionerr>BLAH.</ns1:descriptionerr>
</ns1:responseINFOWL>
</ns1:opINFOWLResponse>
But cannot unmarshal:
<?xml version="1.0" encoding="UTF-8"?>
<ns1:opINFOWLResponse xmlns:ns1="http://www.acme.com/ws"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns1:responseINFOWL xsi:type="ns1:responseINFOWL">
<result>6003</result>
<ndserr />
<transid>61437594</transid>
<descriptionerr>BLAH.</descriptionerr>
</ns1:responseINFOWL>
</ns1:opINFOWLResponse>
This means that the namespace qualification in your JAXB mappings is incorrect. The following may help:
http://blog.bdoughan.com/2010/08/jaxb-namespaces.html
If you could post the class that maps to this section of XML, and the package-info class if there is one, then I can help you modify the mappings.
I had the same problem, in my case, my java service was expecting xml elements without namespace, but the service was reponsing with namespaces. I fixed by adding #XmlElement annotation setting the expected namespace and element name as follows:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "MyResponseType", propOrder = { "someProp" })
public class MyResponseType {
#XmlElement(namespace = "http://www.your-namespace.com/schema/v1.0", name = "someProp")
protected Integer someProp;
}

Java Webservice returning null object to a .net client

Can any one figure out my problem is...
I'm calling a webmethod of a Java Webservice (Axis 1.4) from a .Net client. That method returns a Map object, and if i call it from an Axis client works fine, but in my c# code it´s always null.
That's the WSDL:
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="urn:http.service.enlaces.portlet.ext.com" xmlns:intf="urn:http.service.enlaces.portlet.ext.com" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns1="http://model.enlaces.portlet.ext.com" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:http.service.enlaces.portlet.ext.com">
<wsdl:types>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://xml.apache.org/xml-soap">
<import namespace="urn:http.service.enlaces.portlet.ext.com"/>
<import namespace="http://model.enlaces.portlet.ext.com"/>
<import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
<complexType name="mapItem">
<sequence>
<element name="key" nillable="true" type="xsd:anyType"/>
<element name="value" nillable="true" type="xsd:anyType"/>
</sequence>
</complexType>
<complexType name="Map">
<sequence>
<element maxOccurs="unbounded" minOccurs="0" name="item" type="apachesoap:mapItem"/>
</sequence>
</complexType>
</schema>
</wsdl:types>
<wsdl:message name="getFoldersAndBookmarksRequest" />
<wsdl:message name="getFoldersAndBookmarksResponse">
<wsdl:part name="getFoldersAndBookmarksReturn" type="apachesoap:Map" />
</wsdl:message>
<wsdl:portType name="BookmarksEntryServiceSoap">
<wsdl:operation name="getFoldersAndBookmarks">
<wsdl:input name="getFoldersAndBookmarksRequest" message="intf:getFoldersAndBookmarksRequest" />
<wsdl:output name="getFoldersAndBookmarksResponse" message="intf:getFoldersAndBookmarksResponse" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="Portlet_Bookmarks_BookmarksEntryServiceSoapBinding" type="intf:BookmarksEntryServiceSoap">
<wsdlsoap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc" />
<wsdl:operation name="getFoldersAndBookmarks">
<wsdlsoap:operation soapAction="" />
<wsdl:input name="getFoldersAndBookmarksRequest">
<wsdlsoap:body use="encoded" namespace="urn:http.service.enlaces.portlet.ext.com" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</wsdl:input>
<wsdl:output name="getFoldersAndBookmarksResponse">
<wsdlsoap:body use="encoded" namespace="urn:http.service.enlaces.portlet.ext.com" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
and my c# auto-generated code:
[System.Web.Services.Protocols.SoapRpcMethodAttribute("", RequestNamespace="urn:http.service.enlaces.portlet.ext.com", ResponseNamespace="urn:http.service.enlaces.portlet.ext.com")]
[return: System.Xml.Serialization.SoapElementAttribute("getFoldersAndBookmarksReturn")]
public Map getFoldersAndBookmarks() {
object[] results = this.Invoke("getFoldersAndBookmarks", new object[0]);
return ((Map)(results[0]));
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "2.0.50727.3082")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.SoapTypeAttribute(Namespace="http://xml.apache.org/xml-soap")]
public partial class Map {
private mapItem[] itemField;
/// <comentarios/>
public mapItem[] item {
get {
return this.itemField;
}
set {
this.itemField = value;
}
}
}
I,ve seen everywhere unfortunately, i don't find the solution.
Please, there are anyone what knows it?
I've faced the same problem a while ago. This happens when you try to get an array of elements through an axis webservice with a .net client.
The problem is "name=item" part of this line :
<element maxOccurs="unbounded" minOccurs="0" name="item" type="apachesoap:mapItem"/>
Try changing in that particular line "item" to "mapItem". Try one of these :
<element maxOccurs="unbounded" minOccurs="0" name="mapItem" type="apachesoap:mapItem"/>
or
<element maxOccurs="unbounded" minOccurs="0" name="key" type="apachesoap:mapItem"/>
or
<element maxOccurs="unbounded" minOccurs="0" name="value" type="apachesoap:mapItem"/>
So it very late to help you but I recently was running into the same problem.
Firstly I am using Eclipse to create a web service. The problem for me was that the wsdd generated was using the 'document/literal(wrapped)' style. Changing that to 'RPC' fixed the issue. No more nulls.
So maybe if you change your encoding to RPC that might fix your issue too.
And this is why web services generated from code are almost never interoperable :)
One good way of working around this is to make the wsdl first, and define a nice clear little bit of XSD, that should map nicely into both .Net and java. An alternative is something other than axis 1.4 (yech, the pain) for the server if you have any control over that.
Finally, try massaging the signatures in the java code, try replacing List with MapItem[], or vice versa, make sure you don't have Map anywhere in a return object or a parameter.
Reviewing your generated wsdl again, I'd say this is probably because of the xsd:anyType for the key/value part of the mapItem.
I think that's what is generated by axis if you have a java Object in a parameter. Trust me, you don't want that. Make it a string, or a complex type, or an Integer, but an Object can only imply open ended xml (xsd:anyType) and not many clients no how to parse that.
I faced that, and I had to change WSDL file so:
<wsdlsoap:body use="encoded" ...
to
<wsdlsoap:body use="literal" ...
Only to perform the proxy generation.
I faced same issue. My solution is to remove the Namespace in auto-generated function.
This is my function:
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://www.service-now.com/incident/getRecords", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
[return: System.Xml.Serialization.XmlArrayAttribute("getRecordsResponse", Namespace = "")]
[return: System.Xml.Serialization.XmlArrayItemAttribute("getRecordsResult", Form = System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable = false)]
public getRecordsResponseGetRecordsResult[] getRecords([System.Xml.Serialization.XmlElementAttribute("getRecords", Namespace = "http://www.service-now.com/incident")] getRecords getRecords1)
{
object[] results = this.Invoke("getRecords", new object[] {
getRecords1});
return ((getRecordsResponseGetRecordsResult[])(results[0]));
}
I removed the Namespace in this line. Bacause when I test the web service via SoapUI, I realized that the response object has no namespace. But auto-generated code has namespace.
[return: System.Xml.Serialization.XmlArrayAttribute("getRecordsResponse", Namespace = "")]
SoapUI Response was as following:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<getRecordsResponse>
<getRecordsResult>
<active>0</active>
</getRecordsResult>
</getRecordsResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Categories