CXF客户端调用N种方式

方式一:

配置CXF环境变量,用wsdl2java工具自动产生代码。项目结构目录如下:

其中com.yq.webservice下面的所有的java类都是wsdl2java工具自动产生的。

JaxWsProxyFactoryBean factoryBean = new JaxWsProxyFactoryBean();
factoryBean.getInInterceptors().add(new LoggingInInterceptor());
factoryBean.getOutInterceptors().add(new LoggingOutInterceptor());
factoryBean.setServiceClass(HelloWorldDao.class);
        factoryBean.setAddress(":8080/WebServiceTest/webservice/helloworld?wsdl");
HelloWorldDao impl = (HelloWorldDao) factoryBean.create();
impl.sayHello("zhengmo");

 

其中:
http//:8080/WebServiceTest/webservice/helloworld?wsdl是服务端提供的web service的端口地址。
上面的代码就是WebServiceClient.java中main方法里面的代码。                                      
方式二:

任然需要先用wsdl2java工具生成相应的java代码。
 HelloWorldDaoService factory = new HelloWorldDaoService();
HelloWorldDao helloWorldDao = factory.getHelloWorldDaoPort();
helloWorldDao.sayHello("zhengmo");
方式三:

最后一种方式不需要使用wsdl2java工具在客户端产生代码。

JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance(); 
String wsUrl = "http//:8080/WebServiceTest/webservice/helloworld?wsdl"; 
Client client = dcf.createClient(wsUrl);
String method = "sayHello";//webservice的方法名 
Object[] result = null;
try {
       result = client.invoke(method, "zhengmo");//调用webservice 
} catch (Exception e) {
       e.printStackTrace();
}

CXF提供了很多client端的调用方法。这里让你快速了解这些选择,帮助你判断使用哪种。

参见:

http://cxf.apache.org/docs/how-do-i-develop-a-client.html

源代码主体使用PacktPub.Apache.CXF.Web.Service.Development.Dec.2009书中的代码。本例中,将5种调用方式集中在一个工程中,并使用Maven重组的调用方式。

本例下载地址:

http://dl.iteye.com/topics/download/c647dae6-de86-3eec-9590-7fcf83e9def4

  •   WSDL2Java generated Client
  •   JAX-WS Proxy
  •   JAX-WS Dispatch APIs
  •   JAX-WS Client Proxy
  •   Dynamic Client
    •   Reflection API
    •   Service Model API

在这里Dispatch本节内容不做介绍。

WSDL2Java generated Client

也就是依据wsdl文件生成java客户端,直接调用。查看调用方式,也就是OrderProcessService的getOrderProcessPort方法,获得服务的引用。

启动服务端

mvn test –Pserver

在启动服务端时,通过maven-compiler-plugin编译class,通过cxf-codegen-plugin依据src/main/resources/OrderProcess.wsdl生成存根类OrderProcessService

Xml代码
<plugins>  
            <plugin>  
                <artifactId>maven-compiler-plugin</artifactId>  
                <configuration>  
                    <source>1.5</source>  
                    <target>1.5</target>  
                </configuration>  
            </plugin>  
            <plugin>  
                <groupId>org.apache.cxf</groupId>  
                <artifactId>cxf-codegen-plugin</artifactId>  
                <version>${cxf.version}</version>  
                <executions>  
                    <execution>  
                        <id>generate-sources</id>  
                        <phase>generate-sources</phase>  
                        <configuration>  
                            <wsdlOptions>  
                                <wsdlOption>  
                                    <wsdl>src/main/resources/OrderProcess.wsdl</wsdl>  
                                </wsdlOption>  
                            </wsdlOptions>  
                        </configuration>  
                        <goals>  
                            <goal>wsdl2java</goal>  
                        </goals>  
                    </execution>  
                </executions>  
            </plugin>  
        </plugins>  

启动客户端

mvn test -PStubClient

JAX-WS Proxy

和生成存根类的方式相反,proxy是不需要执行wsdl2java的。但是在编译环境中需要接口类和VO类。这里,通过指定WSDL_LOCATION和PORT_NAME,使用Service.create创建service,使用service.getPort获得服务引用。

Java代码
package demo.order.client;  
  
import java.net.URL;  
import javax.xml.namespace.QName;  
import javax.xml.ws.Service;  
  
import demo.order.Order;  
import demo.order.OrderProcess;  
  
public class ProxyClient {  
  
    private static final QName SERVICE_NAME = new QName("http://order.demo/", "OrderProcessService");  
    private static final QName PORT_NAME = new QName("http://order.demo/", "OrderProcessPort");  
  
    private static final String WSDL_LOCATION = "http://localhost:8080/OrderProcess?wsdl";  
  
    public static void main(String args[]) throws Exception {  
        URL wsdlURL = new URL(WSDL_LOCATION);  
        Service service = Service.create(wsdlURL, SERVICE_NAME);  
        OrderProcess port = service.getPort(PORT_NAME, OrderProcess.class);    
  
        Order order = new Order();  
        order.setCustomerID("C001");  
        order.setItemID("I001");  
        order.setPrice(100.00);  
        order.setQty(20);  
  
        String result = port.processOrder(order);  
        System.out.println("The order ID is " + result);  
          
    }  
      
}  

启动服务端

mvn test –Pserver 

启动客户端

mvn test -PProxyClient

Client Proxy

使用JaxWsProxyFactoryBean 类简化Proxy。

Java代码 
package demo.order.client;  
  
  
import demo.order.Order;  
import demo.order.OrderProcess;  
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;  
  
public class ClientProxyClient {  
  
    public static void main(String args[]) throws Exception {  
        JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();  
        factory.setServiceClass(OrderProcess.class);  
        factory.setAddress("http://localhost:8080/OrderProcess");  
        OrderProcess service = (OrderProcess)factory.create();  
  
        Order order = new Order();  
        order.setCustomerID("C001");  
        order.setItemID("I001");  
        order.setPrice(100.00);  
        order.setQty(20);  
  
        String result = service.processOrder(order);  
        System.out.println("The order ID is " + result);  
          
    }  
      
}  

启动服务端

mvn test –Pserver

启动客户端

mvn test -PClientProxyClient

Dynamic Client 

甚至不需要SEI接口类,

Reflection API

JaxWsDynamicClientFactory.newInstance获得JaxWsDynamicClientFactory实例。通过dcf.createClient获得Client客户端引用。

Java代码  
package demo.order.client;  
  
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;  
import org.apache.cxf.endpoint.Client;  
  
import java.lang.reflect.Method;  
  
public class OrderProcessJaxWsDynamicClient {  
    public OrderProcessJaxWsDynamicClient() {  
    }  
  
    public static void main(String str[]) throws Exception {  
        JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();  
        Client client = dcf.createClient("http://localhost:8080/OrderProcess?wsdl");  
                  
        Object order = Thread.currentThread().getContextClassLoader().loadClass("demo.order.Order").newInstance();  
        Method m1 = order.getClass().getMethod("setCustomerID", String.class);  
        Method m2 = order.getClass().getMethod("setItemID", String.class);  
        Method m3 = order.getClass().getMethod("setQty", Integer.class);  
        Method m4 = order.getClass().getMethod("setPrice", Double.class);  
        m1.invoke(order, "C001");  
        m2.invoke(order, "I001");  
        m3.invoke(order, 100);  
        m4.invoke(order, 200.00);  
                  
        Object[] response = client.invoke("processOrder", order);  
        System.out.println("Response is " + response[0]);  
  
    }  
}  

启动服务端

mvn test –Pserver

启动客户端

mvn test -POrderProcessJaxWsDynamicClient

Service Model API

最后,Service Model是CXF内置的获取Service的信息。

 

Java代码 
package demo.order.client;  
  
import java.beans.PropertyDescriptor;  
import java.util.List;  
  
import javax.xml.namespace.QName;  
  
import org.apache.cxf.endpoint.Client;  
import org.apache.cxf.endpoint.Endpoint;  
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.ServiceInfo;  
  
public class OrderProcessJaxWsDynClient {  
  
    public OrderProcessJaxWsDynClient() {  
    }  
  
    public static void main(String str[]) throws Exception {  
        JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();  
        Client client = dcf.createClient("http://localhost:8080/OrderProcess?wsdl");  
        Endpoint endpoint = client.getEndpoint();  
  
  
        // Make use of CXF service model to introspect the existing WSDL  
        ServiceInfo serviceInfo = endpoint.getService().getServiceInfos().get(0);  
        QName bindingName = new QName("http://order.demo/", "OrderProcessServiceSoapBinding");  
        BindingInfo binding = serviceInfo.getBinding(bindingName);  
        QName opName = new QName("http://order.demo/", "processOrder");  
        BindingOperationInfo boi = binding.getOperation(opName); // Operation name is processOrder  
        BindingMessageInfo inputMessageInfo = null;  
        if (!boi.isUnwrapped()) {  
            //OrderProcess uses document literal wrapped style.  
            inputMessageInfo = boi.getWrappedOperation().getInput();  
        } else {  
            inputMessageInfo = boi.getUnwrappedOperation().getInput();  
        }  
  
        List<MessagePartInfo> parts = inputMessageInfo.getMessageParts();  
        MessagePartInfo partInfo = parts.get(0); // Input class is Order  
  
        // Get the input class Order  
        Class<?> orderClass = partInfo.getTypeClass();  
        Object orderObject = orderClass.newInstance();  
  
        // Populate the Order bean  
        // Set customer ID, item ID, price and quantity  
        PropertyDescriptor custProperty = new PropertyDescriptor("customerID", orderClass);  
        custProperty.getWriteMethod().invoke(orderObject, "C001");  
        PropertyDescriptor itemProperty = new PropertyDescriptor("itemID", orderClass);  
        itemProperty.getWriteMethod().invoke(orderObject, "I001");  
        PropertyDescriptor priceProperty = new PropertyDescriptor("price", orderClass);  
        priceProperty.getWriteMethod().invoke(orderObject, Double.valueOf(100.00));  
        PropertyDescriptor qtyProperty = new PropertyDescriptor("qty", orderClass);  
        qtyProperty.getWriteMethod().invoke(orderObject, Integer.valueOf(20));  
  
        // Invoke the processOrder() method and print the result  
        // The response class is String  
        Object[] result = client.invoke(opName, orderObject);  
        System.out.println("The order ID is " + result[0]);  
    }  
}  

 

//这种方法动态获取服务端对象也可以(亲测成功,jar版本cxf3.0.3)

     JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
    Client client = dcf.createClient("http://localhost:8080/cxfservice/services/getZdxmlist?wsdl");
     
    Object[] result = client.invoke("getZdxmlist", "在建","2016","zd_ctx");
    System.out.println("Echo response: " + result[0]); 
        JSONArray ja=JSONArray.fromObject(result[0]);
        Object objs[]=ja.toArray();
        for (int i = 0; i < objs.length; i++) {
System.out.println(JSONObject.fromObject(objs[i]).get("mc"));//输出各个对象的名称属性
}

有可能汇报这个错误:

CXF 异常 Caused by: org.apache.cxf.binding.soap.SoapFault: Unexpected wrapper element

解决 方法:将客户端中的Service的包名改成与服务端中的一致,问题解决。

http://bbs.csdn.net/topics/390797587

posted @ 2018-04-17 23:28  N神3  阅读(701)  评论(0编辑  收藏  举报