How to specify a java.util.HashMap (key ==> value) in wsdl - java

An existing WebService (written in PHP) specifies an Key, Value Store as xsd:struct. Because Axis doesn't know how to interpretate this, I like to download and patch the Wsdl for my personal use.
At the end, the generated Request should look like this:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:emn="interface.foobar">
<soap:Header/>
<soap:Body>
<emn:searchFoobar>
<emn:searchParameter>
<emn:username>xxxx</emn:username>
<emn:password>xxxx</emn:password>
<emn:maxHitCount>1</emn:maxHitCount>
<emn:sorting>distance</emn:sorting>
<emn:searchtext>example</emn:searchtext>
</emn:searchParameter>
</emn:searchFoobar>
</soap:Body>
</soap:Envelope>
In this example the searchParameter is used as an java.util.HashMap on my client. Its childern are the Key and Value entries.
It's like this:
<emn:hashmapName>
<key1>value1</key1>
<key2>value2</key2>
<key3>value3</key3>
</emn:hashmapName>
The full WSDL looks like this (at the end I like to replace the xsd:struct by an java.util.HashMap):
<?xml version="1.0"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://foobar.service.de/service/v2" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" name="Soap_Manager" targetNamespace="http://foobar.service.de/service/v2">
<types>
<xsd:schema targetNamespace="http://foobar.service.de/service/v2"/>
</types>
<portType name="Soap_ManagerPort">
<operation name="searchFoo">
<documentation>searchFoo</documentation>
<input message="tns:searchFooIn"/>
<output message="tns:searchFooOut"/>
</operation>
</portType>
<binding name="Soap_ManagerBinding" type="tns:Soap_ManagerPort">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="searchFoo">
<soap:operation soapAction="http://foobar.service.de/service/v2#searchFoo"/>
<input>
<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://foobar.service.de/service/v2"/>
</input>
<output>
<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://foobar.service.de/service/v2"/>
</output>
</operation>
</binding>
<service name="Soap_ManagerService">
<port name="Soap_ManagerPort" binding="tns:Soap_ManagerBinding">
<soap:address location="http://foobar.service.de/service/v2"/>
</port>
</service>
<message name="searchFooIn">
<part name="param" type="xsd:struct"/>
</message>
<message name="searchFooOut">
<part name="return" type="xsd:struct"/>
</message>
</definitions>
Could somebody show me how specify a java.util.HashMap for this kind of use?

Download apache axis from here Link to download
Once you download it, unzip it or follow the installation instructions. It comes with a utility called wsdl2java that will read in your wsdl file and build the java classes for it.
I saved your wsdl from above to a file named c:\temp\test.wsdl
Then I ran the wsdl2java command against it like this:
wsdl2java -uri c:\temp\test.wsdl
It generated a source folder with the package names from your wsdl and 2 java classes that can be used to call that service.

Related

SOAP client using wsdl2java and Apache CXF

I ran wsdl2java command using Apache CXF codegen plugin. Excerpt from my WSDL:
<!-- submitSMSv3 -->
<message name="submitSMSv3">
<part name="parameters" element="tns:submitSMSv3"></part>
<!--<part name="gdspHeader" element="tns:gdspHeader"></part>-->
</message>
<message name="submitSMSv3Response">
<part name="result" element="tns:submitSMSv3Response"></part>
</message>
<portType name="SMSv3">
<jaxws:bindings xmlns:jaxws="http://java.sun.com/xml/ns/jaxws">
<jaxws:enableWrapperStyle>true</jaxws:enableWrapperStyle>
</jaxws:bindings>
<operation name="SubmitSMSv3" parameterOrder="parameters">
<input message="tns:submitSMSv3"></input>
<output message="tns:submitSMSv3Response"></output>
</operation>
</portType>
<binding name="SubmitSMSv3PortBinding" type="tns:SMSv3">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"></soap:binding>
<operation name="SubmitSMSv3">
<soap:operation soapAction=""></soap:operation>
<input>
<soap:body use="literal" parts="parameters"></soap:body>
<!--<soap:header message="tns:submitSMSv3" part="gdspHeader" use="literal"></soap:header>-->
</input>
<output>
<soap:body use="literal"></soap:body>
</output>
</operation>
</binding>
<service name="SubmitSMSv3Service">
<port name="SubmitSMSv3Port" binding="tns:SubmitSMSv3PortBinding">
<soap:address location="http://localhost:${HttpDefaultPort}/GDSPWebServices/SMSv3Service"></soap:address>
</port>
</service>
When I invoke the service, my SOAP body looks like this:
<soap:Body>
<ns1:submitSMSv3 xmlns:ns1="http://ws.gdsp.vodafone.com/">
<ns2:arg0 xmlns:ns2="http://ws.gdsp.vodafone.com/">
<deviceId>xxxxxx</deviceId>
<messageData></messageData>
<messageType>Text</messageType>
</ns2:arg0>
</ns1:submitSMSv3>
</soap:Body>
But I don't want the code as it fails the web call, I want my soap body to look like this instead:
<soap:Body>
<ns1:submitSMSv3 xmlns:ns1="http://ws.gdsp.vodafone.com/">
<deviceId>xxxxxxx</deviceId>
<messageData></messageData>
<messageType>Text</messageType>
</ns1:submitSMSv3>
</soap:Body>
I'm not sure what to do in order to get it to be this way as I know this way works.
after many of difficulties with the POJO messaging format, I opted to use PAYLOAD and now everything is working as designed. I had to add a processor for the request and the response but it now works.

Strange WSDL warning during validation in Eclispe: "wsdl:operation was not a request/response or one-way operation"

I'm writing a WSDL file and I can't get rid of this warning from the Eclipse validator:
WS-I: (BP2208) wsdl:operation was not a request/response or one-way operation.
This is the WSDL source I wrote:
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="Master"
targetNamespace="http://pad.polito.it/ACSAuth"
xmlns:tns="http://pad.polito.it/ACSAuth"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns="http://schemas.xmlsoap.org/wsdl/">
<types>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.0"
targetNamespace="http://pad.polito.it/ACSAuth"
xmlns:tns="http://pad.polito.it/ACSAuth">
<xs:element name="AccessDB" type="tns:AccessDBType">
<!-- OMITTED COMPLEX TYPE AccessDBType -->
<xs:element name="passThrough" type="tns:passThroughType"/>
<!-- OMITTED COMPLEX TYPE passThroughType -->
</xs:schema>
</types>
<message name="updatedDB">
<part name="db" element="tns:AccessDB"/>
</message>
<message name="passThroughNotice">
<part name="info" element="tns:passThrough"/>
</message>
<portType name="myPorts">
<operation name="updateManager">
<output name="newUpdate" message="tns:updatedDB"/>
</operation>
<operation name="noticeManager">
<input name="newNotice" message="tns:passThroughNotice"/>
</operation>
</portType>
<binding name="myBindings" type="tns:myPorts">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="updateManager">
<soap:operation soapAction="" />
<output>
<soap:body use="literal"/>
</output>
</operation>
<operation name="noticeManager">
<soap:operation soapAction="" />
<input>
<soap:body use="literal"/>
</input>
</operation>
</binding>
<service name="MyServices">
<port name="ACSAuth" binding="tns:myBindings">
<soap:address location="http://localhost:8181/ACSAuth"/>
</port>
</service>
</definitions>
Here you can find the complete WSDL file: https://dl.dropboxusercontent.com/u/33459047/StackOverflow/Master.wsdl
I believe that the source of the problem is the operation "updateManager", but I don't know how to fix it.
Can someone help me please? Thank you in advance.
An endpoint can support 4 types of operations. From the WSDL specs:
WSDL has four transmission primitives that an endpoint can support:
One-way. The endpoint receives a message.
Request-response. The endpoint receives a message, and sends a correlated message.
Solicit-response. The endpoint sends a message, and receives a correlated message.
Notification. The endpoint sends a message.
The WS-I Profile seems to have a rule for supporting only two of them. From WS-I, Test Assertion: BP2208:
Context:
For a candidate wsdl:operation in a wsdl:portType definition
Assertion Description:
The wsdl:operation element is either a WSDL request/response or a one-way operation (no Notification or Sollicit-Response).
Failure Message:
wsdl:operation was not a request/response or one-way operation.
Your updateManager operation is a Notification and from here your warning.
Clearing the error depends on you interoperability compliance needs. You can either ignore the warning (and then your service won't be 100% interoperability compliant) or you can fix it by changing the operation type (which depends on your application).

Change schemaLocation and soap:address location in runtime generated WSDL with JAX-WS

Is it possible to configure the location (schemaLocation and soap:address location) in a JAX-WS WSDL?
When I deploy the sample below, 'servername' would be localhost and 'serverport' would be the local port number for the web application.
However, I want to reconfigure these to be a proxy servername and serverport which redirects to the service. Is this possible and how would I achieve it?
The deployment environment is Tomcat and Apache.
I have the following service class:
#WebService
public class AuthenticationService {
....
public AuthenticationService(){}
#WebMethod
public AuthenticationResult checkAuthentication(
#WebParam(name = "authentication") Authentication authentication,
#WebParam(name = "privilege") Privilege privilege) {
....
}
}
When ran, the WSDL looks like this:
<definitions targetNamespace="http://authentication.service.ws.ijs/" name="AuthenticationServiceService">
<types>
<xsd:schema>
<xsd:import namespace="http://authentication.service.ws.ijs/" schemaLocation="http://servername:serverport/WebAppName/AuthenticationService?xsd=1"/>
</xsd:schema>
</types>
<message name="checkAuthentication">
<part name="parameters" element="tns:checkAuthentication"/>
</message>
<message name="checkAuthenticationResponse">
<part name="parameters" element="tns:checkAuthenticationResponse"/>
</message>
<portType name="AuthenticationService">
<operation name="checkAuthentication">
<input wsam:Action="http://authentication.service.ws.ijs/AuthenticationService/checkAuthenticationRequest" message="tns:checkAuthentication"/>
<output wsam:Action="http://authentication.service.ws.ijs/AuthenticationService/checkAuthenticationResponse" message="tns:checkAuthenticationResponse"/>
</operation>
</portType>
<binding name="AuthenticationServicePortBinding" type="tns:AuthenticationService">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="checkAuthentication">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="AuthenticationServiceService">
<port name="AuthenticationServicePort" binding="tns:AuthenticationServicePortBinding">
<soap:address location="http://servername:serverport/WebAppName/AuthenticationService"/>
</port>
</service>
</definitions>
Any help would be greatly appreciated.
If you keep the original hostname in your request (e.g use ProxyPreserveHost On if you use mod_proxy) this should fix your URLs, if you use the same protocol. You may still have problems if your proxy switches between https and http.

Perl client to JAX-WS java server issue

I have a JAX-WS java server which publishes a web-service
#WebService(endpointInterface="calculator.operation.Calculator")
public class CalculatorWs implements Calculator{
public String[] add(String a) {
System.out.println(a);
String[] test = {"this", "that"};
System.out.println(test);
return test;
}
}
and
#WebService
#SOAPBinding(style=SOAPBinding.Style.DOCUMENT)
public interface Calculator {
String[] add(String a);
}
and have a perl client
use SOAP::Lite +trace => 'all';
$SOAP::Constants::PREFIX_ENV = 'soapenv';
$SOAP::Constants::PREFIX_ENC = "SOAP-ENC";
my $soap = SOAP::Lite
->service('http://localhost:8080/tomcat/calculator?wsdl')
->soapversion('1.1');
my $var = {'a' => "test"};
my $result = $soap -> add($var);
The problem I'm having is that the Java server does not receive the arguments passed by the Perl client, although the value returned by the Java server is received and recognized by the client.
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsam="http://www.w3.org/2
007/05/addressing/metadata" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/
policy" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="ht
tp://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://operation.calculator/
" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soapenv:Body><tns:add><c-gensym3
><a xsi:type="xsd:string">test</a></c-gensym3></tns:add></soapenv:Body></soapenv
:Envelope>
this is the SOAP request sent by the Perl client. Im assuming the way its building the SOAP request is to blame . But if anyone could help me figure it out, would be greatly appreciated. Thanks.
(edit)
Here is the WSDL generated by JAX-WS:
<?xml version="1.0" encoding="UTF-8" ?>
- <!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.2.3-b01-.
-->
- <!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.2.3-b01-.
-->
- <definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss- wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://operation.calculator/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://operation.calculator/" name="CalculatorWsService">
- <types>
- <xsd:schema>
<xsd:import namespace="http://operation.calculator/" schemaLocation="http://localhost:8080/tomcat/calculator?xsd=1" />
</xsd:schema>
</types>
- <message name="add">
<part name="parameters" element="tns:add" />
</message>
- <message name="addResponse">
<part name="parameters" element="tns:addResponse" />
</message>
- <portType name="Calculator">
- <operation name="add">
<input wsam:Action="http://operation.calculator/Calculator/addRequest" message="tns:add" />
<output wsam:Action="http://operation.calculator/Calculator/addResponse" message="tns:addResponse" />
</operation>
</portType>
- <binding name="CalculatorWsPortBinding" type="tns:Calculator">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" />
- <operation name="add">
<soap:operation soapAction="" />
- <input>
<soap:body use="literal" />
</input>
- <output>
<soap:body use="literal" />
</output>
</operation>
</binding>
- <service name="CalculatorWsService">
- <port name="CalculatorWsPort" binding="tns:CalculatorWsPortBinding">
<soap:address location="http://localhost:8080/tomcat/calculator" />
</port>
</service>
</definitions>
Showing the java function is great for java programmers, you need to show the WSDL or sample SOAP (read XML) invocation ... my guess, all you need
my $result = $soap -> add( 'test');
You should know SOAP::Simple is better at wsdl than SOAP::Lite
I was having the same problem. I made it work with the following two changes:
Name your arguments as in the XSD (http://localhost:8080/tomcat/calculator?xsd=1)
Don't use the default namespace, but a namespace prefix for the SOAP method (ns() method).
Example code:
my $soap = SOAP::Lite
-> proxy('http://localhost:8080/tomcat/calculator')
-> ns ('http://operation.calculator/');
my $response = $soap->call('add', SOAP::Data->name( arg0 => 'Peter Pan'));

WSDL warning: not a SOAP port, it has no soap:address

I get these warnings when I create a Web Service Client using Netbeans v 6.7.1, providing the following wsdl.
parsing WSDL...
[WARNING] port
"ComposedWebServicePort" is not
a SOAP port, it has no soap:address
line 29 of
file:/C:/Users/blavi/Documents/NetBeansProjects/ComposedClient/xml-resources/web-service-references/ComposedWebService/wsdl/ComposedWebService.wsdl
[WARNING] port
"ComposedWebServiceServicePort": not a
standard SOAP port. The generated
artifacts may not work with JAXWS
runtime. line 29 of
file:/C:/Users/blavi/Documents/NetBeansProjects/ComposedClient/xml-resources/web-service-references/ComposedWebService/wsdl/ComposedWebService.wsdl
The WSDL which fires the warnings is:
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" name="ComposedWebService" targetNamespace="http://j2ee.netbeans.org/wsdl/CompositionBpelModule/ComposedWebService" xmlns:ns0="http://www.w3.org/2001/XMLSchema" xmlns:plnk="http://docs.oasis-open.org/wsbpel/2.0/plnktype" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap" xmlns:tns="http://j2ee.netbeans.org/wsdl/CompositionBpelModule/ComposedWebService" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl">
<types/>
<message name="EnterComposition">
<part name="compositionIN" type="ns0:string"/>
</message>
<message name="ExitComposition">
<part name="compositionOUT" type="ns0:string"/>
</message>
<portType name="ComposedWebServicePortType">
<operation name="ComposedWebServiceSOperation">
<input message="tns:EnterComposition" name="input1"/>
<output message="tns:ExitComposition" name="output1"/>
</operation>
</portType>
<binding name="ComposedWebServiceBinding" type="tns:ComposedWebServicePortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="ComposedWebServiceOperation">
<soap:operation soapAction="http://j2ee.netbeans.org/wsdl/CompositionBpelModule/ComposedWebService/ComposedWebServiceOperation" style="document"/>
<input name="input1">
<soap:body use="literal"/>
</input>
<output name="output1">
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="ComposedWebService">
**<port binding="tns:ComposedWebServiceBinding" name="ComposedWebServicePort">**
<soap:address location="http://localhost:8184/ComposedWebService/ComposedWebServicePort"/>
</port>
</service>
<plnk:partnerLinkType name="ComposedWebServicePLT">
<plnk:role name="compositionPartnerLinkType" portType="tns:ComposedWebServicePortType"/>
</plnk:partnerLinkType>
</definitions>
The line marked with ** is line 29 where the warnings appear.
When I try to invoke the web service that has this wsdl, I always get Unsupported Endpoint Address Exception. Can these warnings and exception be related? How can I solve this?
Thank you
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
The SOAP namespace declaration is incorrect; it should have a trailing forward slash.
<part name="compositionOUT" type="ns0:string"/>
If I'm not mistaken, you need an element attribute here.
ComposedWebServiceServiceService
More concise names might make the document a little more readable.

Categories

Resources