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