I'm trying to write a simple web service using Axis2. Its behaviour is really simple: it takes a file in input and stores it.
I've tried several things to do this "simple" file upload service. At the beginning i also tried to use Java2WSDL and WSDL2Java to create the WSDL file and the client hoping to pass the java.io.File datatype. Of course it didn't work.
I'm now trying to upload the file using SOAP attachments and MTOM or SwA.
I've enabled them both in axis2\WEB-INF\conf\axis2.xml
Server side, the signature of my service operation it is:
public String uploadAttachment(OMElement omEle);
And this is the WSDL generated using Java2WSDL tool:
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:ns1="http://org.apache.axis2/xsd" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:xsd="http://services.italsystem.it" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" targetNamespace="http://services.italsystem.it">
<wsdl:types>
<xs:schema attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://services.italsystem.it">
<xs:element name="uploadAttachment">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="omEle" nillable="true" type="xs:anyType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="uploadAttachmentResponse">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="return" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
</wsdl:types>
<wsdl:message name="uploadAttachmentRequest">
<wsdl:part name="parameters" element="xsd:uploadAttachment"/>
</wsdl:message>
<wsdl:message name="uploadAttachmentResponse">
<wsdl:part name="parameters" element="xsd:uploadAttachmentResponse"/>
</wsdl:message>
<wsdl:portType name="ImportServicePortType">
<wsdl:operation name="uploadAttachment">
<wsdl:input message="xsd:uploadAttachmentRequest" wsaw:Action="urn:uploadAttachment"/>
<wsdl:output message="xsd:uploadAttachmentResponse" wsaw:Action="urn:uploadAttachmentResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="ImportServiceSoap11Binding" type="xsd:ImportServicePortType">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<wsdl:operation name="uploadAttachment">
<soap:operation soapAction="urn:uploadAttachment" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="ImportServiceSoap12Binding" type="xsd:ImportServicePortType">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<wsdl:operation name="uploadAttachment">
<soap12:operation soapAction="urn:uploadAttachment" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="ImportServiceHttpBinding" type="xsd:ImportServicePortType">
<http:binding verb="POST"/>
<wsdl:operation name="uploadAttachment">
<http:operation location="uploadAttachment"/>
<wsdl:input>
<mime:content type="application/xml" part="parameters"/>
</wsdl:input>
<wsdl:output>
<mime:content type="application/xml" part="parameters"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="ImportService">
<wsdl:port name="ImportServiceHttpSoap11Endpoint" binding="xsd:ImportServiceSoap11Binding">
<soap:address location="http://localhost:8080/axis2/services/ImportService"/>
</wsdl:port>
<wsdl:port name="ImportServiceHttpSoap12Endpoint" binding="xsd:ImportServiceSoap12Binding">
<soap12:address location="http://localhost:8080/axis2/services/ImportService"/>
</wsdl:port>
<wsdl:port name="ImportServiceHttpEndpoint" binding="xsd:ImportServiceHttpBinding">
<http:address location="http://localhost:8080/axis2/services/ImportService"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Client side, i've tried to call the service:
Options options = new Options();
options.setTo(new EndpointReference("http://localhost:8080/axis2/services/ImportModule"));
options.setProperty(Constants.Configuration.ENABLE_SWA, Constants.VALUE_TRUE);
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
options.setSoapVersionURI(SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI);
ServiceClient sender = new ServiceClient(null,null);
sender.setOptions(options);
OperationClient mepClient = sender.createClient(ServiceClient.ANON_OUT_IN_OP);
MessageContext mc = new MessageContext();
SOAPFactory factory = OMAbstractFactory.getSOAP12Factory();
SOAPEnvelope env = factory.getDefaultEnvelope();
mc.setEnvelope(env);
FileDataSource fileDataSource = new FileDataSource(new File("c:\\test.jpg"));
DataHandler dataHandler = new DataHandler(fileDataSource);
mc.addAttachment("FirstAttachment",dataHandler);
mepClient.addMessageContext(mc);
mepClient.execute(true);
But i get an Axis Fault on the execute call telling me "wrong number of arguments".
I've also tried calling the service using the client generated with WSDL2Java:
ImportServiceStub stub = new ImportServiceStub("http://localhost:8080/axis2/services/ImportModule");
UploadAttachment ua = new UploadAttachment();
FileDataSource fileDataSource = new FileDataSource(new File("c:\\test.jpg"));
DataHandler dataHandler = new DataHandler(fileDataSource);
ua.setOmEle(dataHandler);
UploadAttachmentResponse res = stub.uploadAttachment(ua);
But i get another Axis Fault: "org.apache.axiom.om.impl.llom.OMTextImpl cannot be cast to org.apache.axiom.om.OMElement".
But i don't know what i can give as a parameter to the generated method "setOmEle" since it is an Object type..
i thought to upload a file was one of the simples services that someone can imagine.. :P
i really hope someone can give me some advice, this problem is making me crazy!
thanks in advance :)
It is actually simple: enable MTOM (but not SwA) and use DataHandler as the argument type.
Take a look here, but also would ask to think about using Servlet's doPost; as the thread suggests - Axis2 File Upload by chunk
If you have not seen this, then check this one too for details about the method you are using http://axis.apache.org/axis2/java/core/docs/mtom-guide.html
Andreas' advice was really helpful!
I've tried passing an array of byte to the service, but i has some problems like the size of files on the server weren't of the same size of the files on the client..
With DataHandler i haven't such problems.
I've enabled MTOM in Axis (\WEB-INF\conf\axis2.xml).
My service operation signature was something like that:
public String importFile(String name, DataHandler dh);
And client side, after i've generated the client with WSDL2Java, i used the service as follows:
ImportServiceStub stub = new ImportServiceStub("http://localhost:8080/axis2/services/ImportModule");
ImportFile importFile = new ImportFile(); //operation name
DataSource fds = new FileDataSource(new File("FileName"));
importFile.setName("FileName");
importFile.setDh(new DataHandler(fds));
stub.importFile(importFile);
Thanks again for your support and your advices :)
I could do this successfully when I generate stubs using wsdltojava but when I tried same using wsimport command I am receiving null parameter data at server side.
I am following below process.
Wrote service side code using jax ws specification and mtom soap 11 binding #BindingType(value = SOAPBinding.SOAP11HTTP_MTOM_BINDING)
Generate .aar file to upload it to axis2 server (axis1.6.2 & tomcat 6/7)
Generate wsdl file from axis2 server just clicling on service name.
Generated stubs using wsimport -keep -verbose wsdl url
Test code with with mtom enable
//Enable MTOM
SOAPBinding binding = (SOAPBinding) bp.getBinding();
binding.setMTOMEnabled(true);
Result:- Passing i/p with Sting & byte but i/p received # service method is null
Related
I created WSDL file in Altora XMLSpay and I whant created Web service in Netbeans (Web servicies from WSDL...) but always when add .wsdl file Netbeans write that "There is no service in specified WSDL file." Can you help me? What's wrong with my wsdl documnet?
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="http://new.webservice.namespace" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" targetNamespace="http://new.webservice.namespace">
<wsdl:types>
<xs:schema targetNamespace="http://new.webservice.namespace" elementFormDefault="qualified"/>
</wsdl:types>
<wsdl:message name="NewMessageRequest">
<wsdl:part name="parameter" type="xs:string"/>
</wsdl:message>
<wsdl:message name="NewMessageResponse">
<wsdl:part name="parameter" type="xs:string"/>
</wsdl:message>
<wsdl:portType name="GetDbStatus">
<wsdl:operation name="OpenDB">
<wsdl:input message="tns:NewMessageRequest"/>
<wsdl:output message="tns:NewMessageResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="GetDbStatusBinding" type="tns:GetDbStatus">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="OpenDB">
<soap:operation soapAction="urn:#NewOperation"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="Test_Wsdl">
<wsdl:port name="GetDbstatusPort" binding="tns:GetDbStatusBinding">
<soap:address location="http://localhost:8080/mpo_getdbstatus/GetDbStatus"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
I think your problem in your wsdl
GetDbStatusBinding
The part of the message 'NewMessageRequest' references a schema type instead of a schema element.
The part of the message 'NewMessageResponse' references a schema type instead of a schema element.
It helped me but I have another error:
[ERROR] Schema descriptor {http://www.w3.org/2001/XMLSchema}string in message part "messageReq" is not defined and could not be bound to Java. Perhaps the schema descriptor {http://www.w3.org/2001/XMLSchema}string 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 8 of file:/C:/.../.../mpo_getdbstatus/src/conf/xml-resources/web-services/NewWebServiceFromWSDL/wsdl/mpo_getdbstatus_wsdl.wsdl
C:......\mpo_getdbstatus\nbproject\jaxws-build.xml:31: Error starting wsimport: null
<wsimport sourcedestdir="${build.generated.dir}/jax-wsCache/service/NewWebServiceFromWSDL" destdir="${build.generated.dir}/jax-wsCache/service/NewWebServiceFromWSDL" wsdl="${basedir}/${conf-dir}xml-resources/web-services/NewWebServiceFromWSDL/wsdl/mpo_getdbstatus_wsdl.wsdl" catalog="catalog.xml" encoding="${source.encoding}" extension="true" verbose="true" fork="false" xnocompile="true" xendorsed="true">
<depends file="${basedir}/${conf-dir}xml-resources/web-services/NewWebServiceFromWSDL/wsdl/mpo_getdbstatus_wsdl.wsdl"/>
<produces dir="${build.generated.dir}/jax-wsCache/service/NewWebServiceFromWSDL"/>
</wsimport>
I am trying to generate src from wsdl using following tutorial but getting exception while wsimport.
http://www.mkyong.com/webservices/jax-ws/jax-ws-wsgen-tool-example/
wsimport -keep -verbose
http://localhost:7001/poc-war/ServerInfoService?wsdl
Getting following error :
C:\Program Files\Java\jdk1.8.0_102\bin>wsimport -keep -verbose http://localhost:7001/poc-war/ServerInfoService?wsdl
parsing WSDL...
[ERROR] Server returned HTTP response code: 504 for URL: http://localhost:7001/poc-war/ServerInfoService?wsdl
Failed to read the WSDL document: http://localhost:7001/poc-war/ServerInfoService?wsdl, because 1) could not find the document; /2) the document could not be read; 3) the root element of the document is not <wsdl:definitions>.
[ERROR] Could not find wsdl:service in the provided WSDL(s):
At least one WSDL with at least one service definition needs to be provided.
Failed to parse the WSDL.
ServerInfoService?wsdl
<?xml version='1.0' encoding='UTF-8'?><wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://ws.mkyong.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="ServerInfoService" targetNamespace="http://ws.mkyong.com/">
<wsdl:types>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns0="http://ws.mkyong.com/" targetNamespace="http://ws.mkyong.com/">
<xsd:complexType name="getIpAddressResponse">
<xsd:sequence>
<xsd:element minOccurs="0" name="return" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="getIpAddress"/>
<xsd:element name="getIpAddressResponse" type="ns0:getIpAddressResponse"/>
<xsd:element name="getIpAddress" type="ns0:getIpAddress"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="getIpAddress">
<wsdl:part element="tns:getIpAddress" name="parameters"/>
</wsdl:message>
<wsdl:message name="getIpAddressResponse">
<wsdl:part element="tns:getIpAddressResponse" name="parameters"/>
</wsdl:message>
<wsdl:portType name="ServerInfo">
<wsdl:operation name="getIpAddress">
<wsdl:input message="tns:getIpAddress" name="getIpAddress"/>
<wsdl:output message="tns:getIpAddressResponse" name="getIpAddressResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="ServerInfoServiceSoapBinding" type="tns:ServerInfo">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getIpAddress">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="getIpAddress">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getIpAddressResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="ServerInfoService">
<wsdl:port binding="tns:ServerInfoServiceSoapBinding" name="ARMServicePortTypeImplPort">
<soap:address location="http://10.19.9.92:7001/poc-war/ServerInfoService"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
This is a networking issue. You could open the wsdl in your browser copy and paste the text into a new .wsdl file and regenerate it from the hard drive URL vs a network URL.
I have had times where network security has made it impossible for me to reach WSDL's using some development tools so keeping a copy locally can work. I admit it is a work around at best but 502 is not easy to troubleshoot without a lot more information.
I've got this wsdl supplied for a SOAP 1.1, once I try to generate my java code using wsimport, it handles the wsdl as being 1.2. Which subsiquentially throws an error:
com.sun.tools.ws.wsdl.framework.ParseException: invalid extension element: "soap:body" (in namespace "http://schemas.xmlsoap.org/wsdl/soap/")
If I change the soap name change from:
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap12/
to
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/
It generates my code, but I'm not sure what other consequences this has (I can't yet connect to the endpoint at this time). Plus I don't want to hack the wsdl.
Is there any known error in wsimport that let's it incorrectly handle a 1.1 wsdl as being 1.2? (well, known... I can't find anything about this after hours of searching)
Is there a work around where for example I can force wsimport to use soap 1.1?
Any other solution without editting the wsdl?
wsdl code here:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:rpa="urn:ns:cdm:reisinformatie:data:vi:1" xmlns:tns="urn:ns:cdm:reisinformatie:message:actuelelandelijkeberichten:1" xmlns:ns="urn:ns:cdm:reisinformatie:message:actuelelandelijkeberichten:1" targetNamespace="urn:ns:cdm:reisinformatie:message:actuelelandelijkeberichten:1">
<wsdl:types>
<xsd:schema xmlns:rpa="urn:ns:cdm:reisinformatie:data:vi:1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="urn:ns:cdm:reisinformatie:message:actuelelandelijkeberichten:1" targetNamespace="urn:ns:cdm:reisinformatie:message:actuelelandelijkeberichten:1" elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.0">
<xsd:import schemaLocation="ri-cdm-vi-lab.xsd" namespace="urn:ns:cdm:reisinformatie:data:vi:1"/>
<xsd:element name="GeefActueleLandelijkeBerichtenRequestMessage" type="rpa:GeefActueleLandelijkeBerichtenRequestMessageType"/>
<xsd:element name="GeefActueleLandelijkeBerichtenResponseMessage" type="rpa:GeefActueleLandelijkeBerichtenResponseMessageType"/>
<xsd:element name="GeefActueleLandelijkeBerichtenFaultMessage" type="rpa:GeefActueleLandelijkeBerichtenFaultMessageType"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="GeefActueleLandelijkeBerichtenRequest">
<wsdl:part name="parameter" element="tns:GeefActueleLandelijkeBerichtenRequestMessage"/>
</wsdl:message>
<wsdl:message name="GeefActueleLandelijkeBerichtenResponse">
<wsdl:part name="parameter" element="tns:GeefActueleLandelijkeBerichtenResponseMessage"/>
</wsdl:message>
<wsdl:message name="GeefActueleLandelijkeBerichtenFault">
<wsdl:part name="Fout" element="tns:GeefActueleLandelijkeBerichtenFaultMessage"/>
</wsdl:message>
<wsdl:portType name="ActueleLandelijkeBerichtenSoap">
<wsdl:documentation>Actuele LandelijkeBerichten Soap Port</wsdl:documentation>
<wsdl:operation name="GeefActueleLandelijkeBerichten">
<wsdl:input message="tns:GeefActueleLandelijkeBerichtenRequest"/>
<wsdl:output message="tns:GeefActueleLandelijkeBerichtenResponse"/>
<wsdl:fault name="Fout" message="tns:GeefActueleLandelijkeBerichtenFault"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="ActueleLandelijkeBerichtenSoap" type="tns:ActueleLandelijkeBerichtenSoap">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:documentation>Actuele LandelijkeBerichten Soap Binding</wsdl:documentation>
<wsdl:operation name="GeefActueleLandelijkeBerichten">
<soap:operation soapAction="urn:GeefActueleLandelijkeBerichten"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="Fout">
<soap:body use="literal"/>
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="ActueleLandelijkeBerichten">
<wsdl:documentation>Actuele LandelijkeBerichten Service</wsdl:documentation>
<wsdl:port name="RPAActueleLandelijkeBerichtenSoap" binding="tns:ActueleLandelijkeBerichtenSoap">
<soap:address location="NotDefined"/>
<wsdl:documentation>Reisinformatie Pull Applicatie Actuele LandelijkeBerichten Soap Service</wsdl:documentation>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
note: two .xsd's not included
Right, we've decided to generate the code with CXF (which works) and then add that to the delivery file.
Also, another team at our company ran into same problem and couldn't find a solution for this as well.
So, the answer seems to be: use CXF.
Im creating a JAX-WS webservice on Wildfly 8.0 and consuming it on a VS2013 C# project, what I can't figure out is how can I map a HashMap to .net Dictionary.
My question is, is there a way to create a JAX-WS webservice that is compatible with the .net Dictionary and its automatically converted by the "Add service reference"?
"Add service reference" advanced settings:
Test webservice:
#WebService
#SOAPBinding(style = SOAPBinding.Style.RPC)
#BindingType(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)
public class Test
{
#WebMethod
public HashMap<String, Pojo> echoMap(String input)
{
return new HashMap<String, Pojo>();
}
}
Generated WSDL:
<?xml version='1.0' encoding='UTF-8'?><wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://ws.aiko.com/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="TestService" targetNamespace="http://ws.aiko.com/">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://ws.aiko.com/" targetNamespace="http://ws.aiko.com/" version="1.0">
<xs:element name="facility" type="tns:pojo"/>
<xs:complexType name="pojo">
<xs:sequence>
<xs:element minOccurs="0" name="Name" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<wsdl:message name="echoMapResponse">
<wsdl:part name="return">
</wsdl:part>
</wsdl:message>
<wsdl:message name="echoMap">
<wsdl:part name="arg0" type="xsd:string">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="Test">
<wsdl:operation name="echoMap">
<wsdl:input message="tns:echoMap" name="echoMap">
</wsdl:input>
<wsdl:output message="tns:echoMapResponse" name="echoMapResponse">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="TestServiceSoapBinding" type="tns:Test">
<soap12:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="echoMap">
<soap12:operation soapAction="" style="rpc"/>
<wsdl:input name="echoMap">
<soap12:body namespace="http://ws.aiko.com/" use="literal"/>
</wsdl:input>
<wsdl:output name="echoMapResponse">
<soap12:body namespace="http://ws.aiko.com/" use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="TestService">
<wsdl:port binding="tns:TestServiceSoapBinding" name="TestPort">
<soap12:address location="http://localhost:8080/app/Test"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
I don't think HashMap is interoperable; it also isn't a Java xml type known to JAXB (the framework which turns SOAP XML into java instances which is probably why it's not described in the WSDL.
You can use the tips in this post to provide an adapter Java class which tells the JAXB runtime how to convert your HashMap into an xml structure.
However, I doubt this will be natively consumed by a .Net client as Dictionary. You could try to produce the xml structure described in this article from your Java adapter in the hopes that it will be interpreted as Dictionary.
I learned web services a few years ago with Axis2, and so I've been using it since then.
I've always hated the fact that Axis2 generates client stubs using wrapped parameters instead of the original types. I understand that when you're using complex objects as parameters there's really no choice as those objects need to get serialized, but when your method requires a String and maybe returns a String, wrapping those in some xxx.yyy.Get and xxx.yyy.GetResponse parameters seems like overkill to me. Since I'm using JSON as input and output on all my services now, I'm working with Strings only.
Later in my learnings I discovered I could still create my services with Eclipse's Axis2 plugin, but instead of using the Axis2 stubs, I could use the Java JDK's wsimport tool instead to create clients without all the clutter of the wrapped types.
So, for a service method "String getData(String param)", I could have a client call that looks like "servicePort.getData(stringParam)", where "stringParam" is obviously a String.
That is, until today :-(
For some reason, today I created a new service, deployed it on my server, and called wsimport on it, only to find out that the generated client was using wrapped types.
For example, here's my service definition, from which I create a WSDL and then the service code using Eclipse's Axis2 plugin:
public String get(String param){
return null;
}
And, here's the wsimport-generated client:
#WebMethod
#WebResult(name = "getResponse", targetNamespace = "http://...", partName = "parameters")
public GetResponse get(
#WebParam(name = "get", targetNamespace = "http://...", partName = parameters)
Get parameters);
On a web service I had coded beforehand, I ended up with the following client code :
#WebMethod(action = "urn:get")
#WebResult(targetNamespace = "http://...")
#RequestWrapper(localName = "get", targetNamespace = "http://...", className = "xxx.yyy.Get")
#ResponseWrapper(localName = "getResponse", targetNamespace = "http://...", className = "xxx.yyy.GetResponse")
public String get(
#WebParam(name = "param", targetNamespace = "http://...")
String param);
Here's the wsimport command I'm using to generate the client (on Windows, from my JDK's bin directory) :
.\wsimport -p <package name> -s <target src directory> -extension -verbose -Xnocompile <webserviceUrl?wsdl>
And the wsdl:
<?xml version="1.0" encoding="UTF-8"?><wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:ns1="http://org.apache.axis2/xsd" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:xsd="http://..." xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" targetNamespace="http://...">
<wsdl:types>
<xs:schema attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://...">
<xs:element name="get">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="param" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="getResponse">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="return" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
</wsdl:types>
<wsdl:message name="getRequest">
<wsdl:part name="parameters" element="xsd:get"/>
</wsdl:message>
<wsdl:message name="getResponse">
<wsdl:part name="parameters" element="xsd:getResponse"/>
</wsdl:message>
<wsdl:portType name="ServicePortType">
<wsdl:operation name="get">
<wsdl:input message="xsd:getRequest" wsaw:Action="urn:get"/>
<wsdl:output message="xsd:getResponse" wsaw:Action="urn:getResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="ServiceSoap11Binding" type="xsd:ServicePortType">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<wsdl:operation name="get">
<soap:operation soapAction="urn:get" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="ServiceSoap12Binding" type="xsd:ServicePortType">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<wsdl:operation name="get">
<soap12:operation soapAction="urn:get" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="ServiceHttpBinding" type="xsd:ServicePortType">
<http:binding verb="POST"/>
<wsdl:operation name="get">
<http:operation location="get"/>
<wsdl:input>
<mime:content type="application/xml" part="parameters"/>
</wsdl:input>
<wsdl:output>
<mime:content type="application/xml" part="parameters"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="Service">
<wsdl:port name="ServiceHttpSoap11Endpoint" binding="xsd:ServiceSoap11Binding">
<soap:address location="http://localhost:8080/axis2/services/Service"/>
</wsdl:port>
<wsdl:port name="ServiceHttpSoap12Endpoint" binding="xsd:ServiceSoap12Binding">
<soap12:address location="http://localhost:8080/axis2/services/Service"/>
</wsdl:port>
<wsdl:port name="ServiceHttpEndpoint" binding="xsd:ServiceHttpBinding">
<http:address location="http://localhost:8080/axis2/services/Service"/>
</wsdl:port>
</wsdl:service>
I have found other questions and answers here on StackOverflow and other forums for the "enableWrapperStyle" thing in a custom binding file, tried it, didn't work. Anyhow, this flag seems to allow either generating method signatures with wrapped types (which I don't want), or signatures returning void and using some Holder types in the signature for return values (which I don't want either).
Can someone tell me what I'm doing wrong ?