Yes, IMO this approach is very complicated and we will face more
issues when we are going to integrate with WebService Task. Can you have a
look at [1] and try that ?

​[1] -
http://stackoverflow.com/questions/6849892/whats-a-good-java-library-for-dynamic-soap-client-operations
​

Thanks,
Hasitha.

On Mon, Mar 28, 2016 at 12:07 PM, Natasha Wijesekara <nata...@wso2.com>
wrote:

>  Hi,
>
> There are many complexities when trying to implement a SOAP client using
> the dynamic client capability of Apache CXF. I was able to provide a
> workaround for the error which occurred when passing parameters to a SOAP
> operation with Apache CXF .
>
> The workaround provided does not work with WSDLs which have complex types
> as the request or response message type  i.e. the request/response message
> parts of the WSDL can be primitive or complex, so 2 different approaches
> should be followed to get/set the values of the primitive and complex types
> respectively. When having complex types, the message part is iterated over
> multiple times, which will take more processing time and reduce the
> performance.
>
> The approach I used is described below. By using this approach the
> JaxWsDynamicClientFactory takes care of generating Java classes for complex
> types :
>
> Create a new instance of the Client using the JaxWsDynamicClientFactory by
> passing the wsdl url. The url of the WSDL, operation name and the input
> variables is provided by the user.
>
>
>
>
>
> *JaxWsDynamicClientFactory factory =
> JaxWsDynamicClientFactory.newInstance();URL wsdlURL = new
> URL("http://localhost:9763/services/DivisionProcessService?wsdl
> <http://10.100.4.192:9763/services/DivisionProcessService?wsdl>");String
> operationName = "process";Client client =
> factory.createClient(wsdlURL.toExternalForm());ClientImpl clientImpl =
> (ClientImpl) client;*
>
> Get the endpoint i.e. the URL where the web service can be accessed by a
> client application using the cilent.
>
> *Endpoint endpoint = clientImpl.getEndpoint();*
>
> Get the target namespace of the WSDL by creating a ServiceInfo object
> which walks over the CXF service model
>
> *ServiceInfo serviceInfo = endpoint.getService().getServiceInfos().get(0);*
> *String targetNameSpace = serviceInfo.getTargetNamespace();*
>
> Get the binding name of the WSDL by creating a BindingInfo object which
> gets the name of the binding.
>
> *BindingInfo bindingInfo = serviceInfo.getBindings().iterator().next();*
> *String bName = bindingInfo.getName().getLocalPart();*
>
> Create a Qname by passing the namespace and the binding name as parameters
> and get the binding which has the specified QName.
>
> *QName bindingName = new QName(targetNameSpace, bName);*
> *BindingInfo binding = serviceInfo.getBinding(bindingName);*
>
> Get details about the soap operation which is to be invoked by creating a
> QName with the namespace and the operation name.
>
> *QName opName = new QName(targetNameSpace, operationName);*
> *BindingOperationInfo boi = binding.getOperation(opName);*
>
> Get the input/request message type
> *BindingMessageInfo inputMessageInfo = boi.getInput();*
> *List<MessagePartInfo> parts = inputMessageInfo.getMessageParts();*
> *MessagePartInfo partInfo = parts.get(0);*
>
> Get the  class type of the request/input message and dynamically create an
> instance of it
> *Class<?> partClass = partInfo.getTypeClass();*
> *Object obj = partClass.newInstance();*
>
> The input variables provided by the user is stored inside a  HashTable
> which will hold the variable name and its value as a key-value pair
>
> *Hashtable table = new Hashtable();*
> *table.put("dividend", 40);*
> *table.put("divisor", 10);*
>
> Get the methods from the generated request class. This class will have
> getter and setter methods for the variables taken as the input/request.
>
> *Method [] methods = obj.getClass().getDeclaredMethods();*
> *for(Method m : methods){*
> * if(m.getName().contains("set")){*
> * String methodName = m.getName(); *
> * Class<?> paramType = m.getParameterTypes()[0];*
> * String[] output = methodName.split("set");*
> * String varName = output[1].toLowerCase(); *
> * Object value = table.get(varName); *
> * Method m1 = obj.getClass().getMethod(methodName, paramType); *
> * m1.invoke(obj, value);*
> * } else {*
> * }*
> *}*
>
> Invoking the operation
> *Object[] response = client.invoke(operationName, obj);*
>
> Get the methods from the generated response class. This class will have getter
> and setter methods for the variables given as the output.
>
> *Method [] responseMethods = response[0].getClass().getDeclaredMethods();*
> *for(Method rm : responseMethods){*
> * if(rm.getName().contains("get")){*
> * String responseMethod = rm.getName();*
> * Object result =
> response[0].getClass().getMethod(responseMethod).invoke(response[0]);*
> * System.**out**.println("Response: " + result);*
> * } else {*
> * }*
> *}*
>
> Is this approach correct or is there any way to overcome these limitations
> when using CXF ?
>
> Any suggestions and feedback are highly appreciated.
>
> Best Regards,
>
> Natasha Wijesekare
>
> On Thu, Mar 17, 2016 at 4:47 PM, Natasha Wijesekara <nata...@wso2.com>
> wrote:
>
>> Hi ,
>>
>> I tried passing the operation name with the namespace but it didn't work.
>> I get the same exception as below.
>>
>> *java.lang.IllegalArgumentException: Part
>> {http://wso2.org/wso2con/2011/sample/adder}payload
>> <http://wso2.org/wso2con/2011/sample/adder%7Dpayload> should be of type
>> org.wso2.wso2con._2011.sample.adder.AdderProcessRequest, not
>> java.lang.Integer*
>> * at
>> org.apache.cxf.jaxb.io.DataWriterImpl.checkPart(DataWriterImpl.java:284)*
>> * at org.apache.cxf.jaxb.io.DataWriterImpl.write(DataWriterImpl.java:212)*
>> * at
>> org.apache.cxf.interceptor.AbstractOutDatabindingInterceptor.writeParts(AbstractOutDatabindingInterceptor.java:122)*
>> * at
>> org.apache.cxf.interceptor.BareOutInterceptor.handleMessage(BareOutInterceptor.java:68)*
>> * at
>> org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)*
>> * at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:572)*
>> * at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:481)*
>> * at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:382)*
>> * at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:335)*
>> * at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:355)*
>> * at cxfClient_1.main(cxfClient_1.java:61)*
>> * at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)*
>> * at
>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)*
>> * at
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)*
>> * at java.lang.reflect.Method.invoke(Method.java:606)*
>> * at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)*
>>
>> Best Regards,
>> Natasha Wijesekare
>>
>> On Thu, Mar 17, 2016 at 3:39 PM, Himasha Guruge <himas...@wso2.com>
>> wrote:
>>
>>> Hi Natasha,
>>>
>>> Can you try passing the operation name with the namespace as well?
>>>
>>> Regards,
>>> Himasha
>>>
>>> On Thu, Mar 17, 2016 at 2:16 PM, Natasha Wijesekara <nata...@wso2.com>
>>> wrote:
>>>
>>>> Hi,
>>>>
>>>> I'm trying to invoke an external soap service operation which takes
>>>> integers as the parameters.
>>>>
>>>> *Request Body of the Soap Service *:
>>>>
>>>> *<soapenv:Envelope
>>>> xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/
>>>> <http://schemas.xmlsoap.org/soap/envelope/>"
>>>> xmlns:add="http://wso2.org/wso2con/2011/sample/adder
>>>> <http://wso2.org/wso2con/2011/sample/adder>">*
>>>> *   <soapenv:Header/>*
>>>> *   <soapenv:Body>*
>>>> *      <add:AdderProcessRequest>*
>>>> *         <add:a>?</add:a>*
>>>> *         <add:b>?</add:b>*
>>>> *      </add:AdderProcessRequest>*
>>>> *   </soapenv:Body>*
>>>> *</soapenv:Envelope>*
>>>>
>>>> I have created a client to invoke the soap operation using
>>>> JaxWsDynamicClientFactory.
>>>> JaxWsDynamicClientFactory clientFactory =
>>>> JaxWsDynamicClientFactory.newInstance();
>>>>
>>>> I have invoked the operation by passing the operation name and the
>>>> parameters to the client.
>>>> When multiple parameters of type *string* is passed, no error is given.
>>>>
>>>> In this request I need to pass 2 *integers* as the parameters as shown
>>>> below :
>>>> client.invoke("operationName", num1, num2);
>>>> But when I do so I get the following error :
>>>>
>>>> *java.lang.IllegalArgumentException: Part
>>>> {http://wso2.org/wso2con/2011/sample/adder}payload
>>>> <http://wso2.org/wso2con/2011/sample/adder%7Dpayload> should be of type
>>>> org.wso2.wso2con._2011.sample.adder.AdderProcessRequest, not
>>>> java.lang.Integer*
>>>> * at
>>>> org.apache.cxf.jaxb.io.DataWriterImpl.checkPart(DataWriterImpl.java:284)*
>>>> * at
>>>> org.apache.cxf.jaxb.io.DataWriterImpl.write(DataWriterImpl.java:212)*
>>>> * at
>>>> org.apache.cxf.interceptor.AbstractOutDatabindingInterceptor.writeParts(AbstractOutDatabindingInterceptor.java:122)*
>>>> * at
>>>> org.apache.cxf.interceptor.BareOutInterceptor.handleMessage(BareOutInterceptor.java:68)*
>>>> * at
>>>> org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)*
>>>> * at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:572)*
>>>> * at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:481)*
>>>> * at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:382)*
>>>> * at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:335)*
>>>> * at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:355)*
>>>> * at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:341)*
>>>>
>>>>  Appreciate any help on this.
>>>>
>>>> Best Regards,
>>>> *Natasha Wijesekare*
>>>>
>>>> *Software Engineering Intern, WSO2  Inc:  http://wso2.com
>>>> <http://wso2.com/>*
>>>> *email  : nata...@wso2.com <nata...@wso2.com>*
>>>> *mobile: +94 771358651 <%2B94%20771358651>*
>>>>
>>>> _______________________________________________
>>>> Dev mailing list
>>>> Dev@wso2.org
>>>> http://wso2.org/cgi-bin/mailman/listinfo/dev
>>>>
>>>>
>>>
>>>
>>> --
>>> Himasha Guruge
>>> *Software Engineer*
>>> WS*O2* *Inc.*
>>> Mobile: +94 777459299
>>> himas...@wso2.com
>>>
>>
>>
>>
>> --
>> *Natasha Wijesekare*
>>
>> *Software Engineering Intern, WSO2  Inc:  http://wso2.com
>> <http://wso2.com/>*
>> *email  : nata...@wso2.com <nata...@wso2.com>*
>> *mobile: +94 771358651 <%2B94%20771358651>*
>>
>
>
>
> --
> *Natasha Wijesekare*
>
> *Software Engineering Intern, WSO2  Inc:  http://wso2.com
> <http://wso2.com/>*
> *email  : nata...@wso2.com <nata...@wso2.com>*
> *mobile: +94 771358651 <%2B94%20771358651>*
>
> _______________________________________________
> Dev mailing list
> Dev@wso2.org
> http://wso2.org/cgi-bin/mailman/listinfo/dev
>
>


-- 
--
Hasitha Aravinda,
Senior Software Engineer,
WSO2 Inc.
Email: hasi...@wso2.com
Mobile : +94 718 210 200
_______________________________________________
Dev mailing list
Dev@wso2.org
http://wso2.org/cgi-bin/mailman/listinfo/dev

Reply via email to