Multiple wsdl:part elements in input message of SOAP operation - java

I am trying to rewrite existing service from Axis 1 to Spring WS. I have been looking at a lot of examples and simple tutorials but none of them uses multiple parts in input message of SOAP operation.
Does Spring WS allow binding multiple wsdl:parts to a function parameters in #Endpoint class? If it does, how?
My input message looks like this:
<wsdl:message name="getMetricDataRequest">
<wsdl:part name="agent" type="xsd:string"/>
<wsdl:part name="metric" type="xsd:string"/>
<wsdl:part name="startTime" type="xsd:dateTime"/>
<wsdl:part name="endTime" type="xsd:dateTime"/>
</wsdl:message>

Related

Adding one part into another part in WSDL4J

I am generating WSDL dynamically using WSDL4J and I am able to create a WSDL file, but I want a nested structure (I mean, I want to declare a complex element and add it into the message).
So I want to add the TestService element into the wsdl:message TestServiceRequest dynamically using Java code and WSDL4J...
<element name="TestService">
<complexType>
<sequence>
<element name="servicetag" type="xsd:string"/>
<element name="header" type="xsd:string"/>
<element name="requestparam" type="xsd:string"/>
<element name="body" type="xsd:string"/>
</sequence>
</complexType>
</element>
<wsdl:message name="TestServiceRequest">
<wsdl:part name="parameters" element="tns:TestService">
</wsdl:part>
</wsdl:message>
How can I achieve that?

Four different wsdl2java apps fail to import wsdl, but SoapUI does fine

There is a public service, and as far as I know, they have dozens or hundreds of clients. But I cannot generate classes from provided WSDL.
http://api.kartoteka.ru/search/v3/soap/search.wsdl
I tried wsimport from latest jdk8, and wsdl2java from axis1, axis2, cxf
All apps fail. The most interesting thing is that SoapUI processed this WSDL without any errors.
I've "fixed" the first error about Duplicate keys by downloading wsdl and "patching" it, but next error is a bit complex for me:
[ERROR] undefined simple or complex type 'Error'
line 15 of http://api.kartoteka.ru/core/v3/soap/core.wsdl
probably the first problem is also related to namespaces, and no duplicates really exist. The warning is rather verbose, but it's unclear what changes should I make.
[WARNING] src-resolve.4.1: Error resolving component 'Error'. It was detected that 'Error' has no namespace, but components with no target namespace are not referenceable from schema document 'http://api.kartoteka.ru/core/v3/soap/core.wsdl#types?schema1'. If 'Error' is intended to have a namespace, perhaps a prefix needs to be provided. If it is intended that 'Error' has no namespace, then an 'import' without a "namespace" attribute should be added to 'http://api.kartoteka.ru/core/v3/soap/core.wsdl#types?schema1'.
line 15 of http://api.kartoteka.ru/core/v3/soap/core.wsdl#types?schema1
[WARNING] src-resolve: Cannot resolve the name 'Error' to a(n) 'type definition' component.
line 15 of http://api.kartoteka.ru/core/v3/soap/core.wsdl#types?schema1
[WARNING] src-resolve.4.1: Error resolving component 'Error'. It was detected that 'Error' has no namespace, but components with no target namespace are not referenceable from schema document 'file:/tmp/kart/search.wsdl#types?schema3'. If 'Error' is intended to have a namespace, perhaps a prefix needs to be provided. If it is intended that 'Error' has no namespace, then an 'import' without a "namespace" attribute should be added to 'file:/tmp/kart/search.wsdl#types?schema3'.
line 26 of file:/tmp/kart/search.wsdl#types?schema3
I found no options for namespaces in wsimport, so in general it looks like a wrong way to modify wsdl, maybe I'm missing something easy?
The problem is that the inline schema definitions in core.wsdl and search.wsdl do not have namespace defined for the target namespace (to which all defined elements belong to). The target namespace indicates that the vocabulary defined in this inline schema (talking about core.wsdl now only for simplicity) belong to a namespace "http://api.kartoteka.ru/core/v3/". So when the already defined vocabulary (complexType Error in this case) is referenced later on without any prefix it means that it should come from the default namespace. The default namespace is not defined in <xs:schema targetNamespace="http://api.kartoteka.ru/core/v3/">, but it should be taken from:
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://api.kartoteka.ru/core/v3/" targetNamespace="http://api.kartoteka.ru/core/v3/">
Because as stated in the XML names spec, section 6.2, it should be inherited :
The scope of a default namespace declaration extends from the
beginning of the start-tag in which it appears to the end of the
corresponding end-tag, excluding the scope of any inner default
namespace declarations. In the case of an empty tag, the scope is the
tag itself.
A default namespace declaration applies to all unprefixed element
names within its scope. Default namespace declarations do not apply
directly to attribute names; the interpretation of unprefixed
attributes is determined by the element on which they appear.
If there is a default namespace declaration in scope, the expanded
name corresponding to an unprefixed element name has the URI of the
default namespace as its namespace name. If there is no default
namespace declaration in scope, the namespace name has no value. The
namespace name for an unprefixed attribute name always has no value.
In all cases, the local name is local part (which is of course the
same as the unprefixed name itself).
I think that wsimport's behaviour is wrong as it does not take default namespace from the parent element. Adding default namespace is enough to "fix" this. So you only need to change one line for core.wsdl (line 8):
<xs:schema xmlns="http://api.kartoteka.ru/core/v3/" targetNamespace="http://api.kartoteka.ru/core/v3/">
and one line for search.wsdl (line 7):
<xs:schema xmlns="http://api.kartoteka.ru/search/v3/" targetNamespace="http://api.kartoteka.ru/search/v3/" elementFormDefault="qualified">
I am leaving other workarounds (below) which I wrote earlier but they are more complex (compared to this one) and aren't actually needed.
Maybe the simplest one is to make necessary changes to use namespaces in the embedded schema definitions.
In search.wsdl make these changes (line 7 and line 26):
<xs:schema xmlns:tns="http://api.kartoteka.ru/search/v3/" targetNamespace="http://api.kartoteka.ru/search/v3/" elementFormDefault="qualified">
and
<xs:element name="error" type="tns:Error"/>
In core.wsdl make similar changes (line 8 and lines 15-18):
<xs:schema xmlns:tns="http://api.kartoteka.ru/core/v3/" targetNamespace="http://api.kartoteka.ru/core/v3/">
and
<xs:element name="systemError" type="tns:Error" />
<xs:element name="serviceRestriction" type="tns:Error" />
<xs:element name="authorizationRestriction" type="tns:Error" />
Another way would be to define Error complexType outside of the wsdl file and import it in your core.wsdl and search.wsdl files.
Create external schema file: common.xsd with contents like this:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://mycustomschema/common/"
targetNamespace="http://mycustomschema/common/">
<xs:complexType name="Error">
<xs:sequence>
<xs:element name="code" type="xs:positiveInteger"/>
<xs:element name="msg" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
Reference your custom complexType in search.wsdl:
<xs:import namespace="http://mycustomschema/common/" schemaLocation="common.xsd"/>
<xs:element name="sessionId" type="xs:string"/>
<xs:element xmlns:common="http://mycustomschema/common/" name="error" type="common:Error"/>
Reference your custom complexType in core.wsdl:
<xs:import namespace="http://mycustomschema/common/" schemaLocation="common.xsd"/>
<xs:element xmlns:common="http://mycustomschema/common/" name="systemError" type="common:Error" />
<xs:element xmlns:common="http://mycustomschema/common/" name="serviceRestriction" type="common:Error" />
<xs:element xmlns:common="http://mycustomschema/common/" name="authorizationRestriction" type="common:Error" />
One more method is to change element="error" to type="Error":
Remove this line from search.wsdl:
<xs:element name="error" type="Error"/>
Change these lines in search.wsdl:
<wsdl:message name="SearchError">
<wsdl:part name="searchError" type="Error"/>
</wsdl:message>
<wsdl:message name="CardError">
<wsdl:part name="cardError" type="Error"/>
</wsdl:message>
<wsdl:message name="ImportantFactsError">
<wsdl:part name="importantFactsError" type="Error"/>
</wsdl:message>
<wsdl:message name="PledgeError">
<wsdl:part name="pledgeError" type="Error"/>
</wsdl:message>
<wsdl:message name="VocabularyError">
<wsdl:part name="vocabularyError" type="Error"/>
</wsdl:message>
<wsdl:message name="BoYearsRequest">
<wsdl:part name="request" type="bo:orgBoYearsRequest"/>
</wsdl:message>
<wsdl:message name="BoYearsResponse">
<wsdl:part name="response" type="bo:orgBoYearsResponse"/>
</wsdl:message>
<wsdl:message name="BoError">
<wsdl:part name="boError" type="Error"/>
</wsdl:message>
Remove these lines from search.wsdl:
<xs:element name="systemError" type="Error" />
<xs:element name="serviceRestriction" type="Error" />
<xs:element name="authorizationRestriction" type="Error" />
Change these lines in search.wsdl:
<wsdl:message name="SystemError">
<wsdl:part name="systemError" type="Error"/>
</wsdl:message>
<wsdl:message name="ServiceRestriction">
<wsdl:part name="serviceRestriction" type="Error"/>
</wsdl:message>
<wsdl:message name="AuthorizationRestriction">
<wsdl:part name="authorizationRestriction" type="Error"/>
</wsdl:message>
This way you can use the type defined in embedded schema definition directly and wsimport seems to understand the wsdl file this way.

Java: Invoke web service using Axis2 stub class

I'm new to web services. With all difficulty I have generated a simple 'Hello World' web service :D. I want to invoke the web service using java. The web service has a hard coded value shown as the output. Here is what I have tried.
I have created a new Dynamic web Project in Eclipse for web service client.
To this project generated stub classes for the web service using Axis2 and Eclipse.
I am not able to understand what the generated stub class basically contain, and how to use the stub class to invoke the webservice.
The stub class generated has too many lines of code. which i cannot paste it here; Is there any particular class that i need to concentrate on inorder to invoke a method in the webservice?
Part of the wsdl look like this
<wsdl:types>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://sample.com/Webservice/wsTest" targetNamespace="http://sample.com/Webservice/wsTest">
<xsd:element name="test" type="tns:test"/>
<xsd:element name="testResponse" type="tns:testResponse"/>
<xsd:complexType name="test">
<xsd:sequence></xsd:sequence>
</xsd:complexType>
<xsd:complexType name="testResponse">
<xsd:sequence>
<xsd:element name="outputString" nillable="true" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</wsdl:types>
<wsdl:message name="wsTest_PortType_test">
<wsdl:part name="parameters" element="tns:test"></wsdl:part>
</wsdl:message>
Could you please let me know how to invoke a web service using Java in eclipse.
Later part: In case my webservice has input(eg: web service for addition) how do i pass the request parameters and get an output as a response.
I think this will definitely helps you
Just go through step by step procedure according to it,then you can achieve easily your Requirement.
the Link is here:
http://www.ibm.com/developerworks/webservices/library/ws-apacheaxis/index.html?ca=dat

Validate jaxws soap request against schema inside wsdl:types

I'm wanting to validate a soap request against the schema inside this wsdl.
<wsdl:types >
<xsd:schema targetNamespace="http://ws.thecompany.com/FormSubmissionService20100824"
xmlns:request="http://xmlschema.thecompany.com/generic/FormHeader20100824" xmlns:response="http://xmlschema.thecompany.com/generic/FormResponse20100824">
<xsd:import namespace="http://xmlschema.thecompany.com/generic/FormHeader20100824" schemaLocation="../schema/generic/FormHeader20100824.xsd"/>
<xsd:import namespace="http://xmlschema.thecompany.com/generic/FormResponse20100824" schemaLocation="../schema/generic/FormResponse20100824.xsd"/>
<xsd:element name="submitFormRequest" type="request:FormHeader"/>
<xsd:element name="submitFormResponse" type="response:FormResponse"/>
</xsd:schema>
</wsdl:types>
<!-- Message Definition -->
<wsdl:message name="submitFormRequest">
<wsdl:part element="thecomp:submitFormRequest" name="request" />
</wsdl:message>
Loading a javax.xml.validation.Validator for the schema validating against a < thecomp:submitFormRequest> element doesn't work, neither does attempting to load the wsdl as the schema.
Ideas please?
(using jax-ws, was7)
Cheers
I extracted the request/response into its own schema file:
<wsdl:types >
<xsd:schema>
<xsd:import namespace="http://ws.acc.co.nz/ACCFormSubmissionService20100824"
schemaLocation="../schema/ws/ACCFormSubmissionService20100824.xsd" />
</xsd:schema>
</wsdl:types>
Validating against the new schema namespace/xsd works as required.

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