Question

I wrote the small application below to list all the methods and of a soap service using Apache CXF library. This application lists all the methods of the service, but as it is seen on the output when you run this application, input parameters and return types of the service methods are JAXBElement for the complex types. I want cxf not to generate JAXBElement, instead I want the complex types in their original classes generated on runtime. As it is said on http://s141.codeinspot.com/q/1455881 , it can be done by setting generateElementProperty property's value to false for wsdl2java utility of cxf library, but I couldn't find the same parameter for dynamic method invocation with cxf library. I want to obtain input parameters and return types in their original types.

import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;
import java.util.List;
import org.apache.cxf.binding.Binding;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.apache.cxf.service.model.BindingInfo;
import org.apache.cxf.service.model.BindingMessageInfo;
import org.apache.cxf.service.model.BindingOperationInfo;
import org.apache.cxf.service.model.MessagePartInfo;
import org.apache.cxf.service.model.OperationInfo;
import org.apache.cxf.service.model.ServiceModelUtil;

public class Main {

    public static void main(String[] args) {
        URL wsdlURL = null;
        try {
            wsdlURL = new URL("http://path_to_wsdl?wsdl");
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
        Client client = dcf.createClient(wsdlURL, classLoader);
        Binding binding = client.getEndpoint().getBinding();
        BindingInfo bindingInfo = binding.getBindingInfo();
        Collection<BindingOperationInfo> operations = bindingInfo.getOperations();
        for(BindingOperationInfo boi:operations){
            OperationInfo oi = boi.getOperationInfo();
            BindingMessageInfo inputMessageInfo = boi.getInput();
            List<MessagePartInfo> parts = inputMessageInfo.getMessageParts();
            System.out.println("function name: "+oi.getName().getLocalPart());
            List<String> inputParams = ServiceModelUtil.getOperationInputPartNames(oi);
            System.out.println("input parameters: "+inputParams);
            for(MessagePartInfo partInfo:parts){
                Class<?> partClass = partInfo.getTypeClass();       //here we have input parameter object on each iteration
                Method[] methods = partClass.getMethods();
                for(Method method:methods){
                    System.out.println("method: "+method);
                    Class<?>[] paramTypes = method.getParameterTypes();
                    for(Class paramType:paramTypes){
                        System.out.println("param: "+paramType.getCanonicalName());                     
                    }
                    Class returnType = method.getReturnType();
                    System.out.println("returns: "+returnType.getCanonicalName());
                }
                System.out.println("partclass: "+partClass.getCanonicalName());
            }
        }
        System.out.println("binding: " + binding);
        }
}
Was it helpful?

Solution

Create a binding file that looks like:

<jaxb:bindings
  xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.0"
  xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" jaxb:extensionBindingPrefixes="xjc">

  <jaxb:globalBindings generateElementProperty="false">
    <xjc:simple />
  </jaxb:globalBindings>
</jaxb:bindings>

and pass that into the JaxWsDynamicClientFactory via the createClient method that takes the List of binding files.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top