CXF WebService

来源:互联网 发布:双十一淘宝销售培训 编辑:程序博客网 时间:2024/05/17 04:14

一、 准备工作

1、  CXF官方网址:http://cxf.apache.org/

2、  Jar包下载地址:http://www.apache.org/dyn/closer.cgi?path=/cxf/2.3.3/apache-cxf-2.3.3.zip

将下来的jar包解压后,目录大概就这样

bin目录提供的是常用的dos控制台命令工具

docs 帮助文档

lib jar包、依赖库

lib-samples 也是jar包,有jetty、httpclients、junit等jar包

modules 打包好的WebService模块

samples示例demo

3、  源码下载:http://www.apache.org/dyn/closer.cgi?path=/cxf/2.3.3/apache-cxf-2.3.3-src.zip

有时候你可以看看源码,对你了解和学习CXF WebService都会有作用。

4、  CXF的特性

有代码生成工具:Java to WSDL;WSDL to Java;XSD to WSDL;WSDL to XML;WSDL to SOAP;WSDL to Service;

支持 JAX-WS、 JAX-WSA、JSR-181 和 SAAJ;支持SOAP 1.1、1.2、WS-I BasicProfile、WS-Security、WS-Addressing、WS-RM 和 WS-Policy;支持 WSDL 1.1 、2.0;支持MTOM;、JavaScript、通过 Yoko 支持 CORBA;通过 Tuscany 支持 SCA;通过 ServiceMix 支持 JBI

内置Jetty应用服务器

 

二、 CXF 入门实例

又一HelloWorld示例,老套的HelloWorld是入门经典。也是基础和必须掌握的,下面看看HelloWorldWebService,很简单。

需要的jar包如下:

1、  HelloWorldService服务器端代码

package com.hoo.service;

 

import javax.jws.WebParam;

importjavax.jws.WebService;

import javax.jws.soap.SOAPBinding;

import javax.jws.soap.SOAPBinding.Style;

 

/**

 * <b>function:</b>CXF WebService服务器端helloWorld示例

 * @authorhoojo

 * @createDate 2011-3-16上午08:29:07

 * @file HelloWorld.java

 * @package com.hoo.service

 * @project CXFWebService

 * @blog http://blog.csdn.net/IBM_hoojo

 * @email hoojo_@126.com

 * @version 1.0

 */

@WebService

@SOAPBinding(style = Style.RPC)

publicclass HelloWorldService {

   

    public String sayHello(@WebParam(name ="name") String name) {

       return name +" say: Hello World ";

    }

}

要说明的是,上面的服务器端代码运用了JDK5的新特性Annotation,这个非常好用。

需要注意的是,如果不添加@SOAPBinding(style = Style.RPC)注解,将会出现异常:

com.sun.xml.internal.ws.model.RuntimeModelerException: runtime modeler error

还有就是如果jdk版本在1.6下,也会出现上面的异常。

解决办法有:

1> 先用apt命令将主程序进行编译,然后生成一些java文件

2> 升级JDK到版本jdk1.6u17或以后

2、  发布HelloWorldService,代码如下:

package com.hoo.service.deploy;

 

import javax.xml.ws.Endpoint;

import com.hoo.service.HelloWorldService;

 

/**

 * <b>function:</b>发布CXF WebService

 * @authorhoojo

 * @createDate 2011-3-17上午09:24:33

 * @file DeployHelloWorldService.java

 * @package com.hoo.deploy

 * @project CXFWebService

 * @blog http://blog.csdn.net/IBM_hoojo

 * @email hoojo_@126.com

 * @version 1.0

 */

publicclass DeployHelloWorldService {

   

    /**

     * <b>function:</b>发布WebService

     * @authorhoojo

     */

    publicstaticvoid deployService() {

       System.out.println("Server start ……");

       HelloWorldService service =new HelloWorldService();

       String address = "http://localhost:9000/helloWorld";

       Endpoint.publish(address, service);

    }

   

    publicstaticvoid main(String[] args)throws InterruptedException {

       //发布WebService

       deployService();

       System.out.println("server ready ……");

       Thread.sleep(1000 * 60);

       System.out.println("server exiting");

       //休眠60秒后就退出

       System.exit(0);

    }

}

运行上面的main函数后,如果没有发现异常。基本信息是这样的:

Server start ……

2011-3-17 10:17:25 org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromClass

信息: Creating Service {http://service.hoo.com/}HelloWorldServiceService from class com.hoo.service.HelloWorldService

2011-3-17 10:17:25 org.apache.cxf.endpoint.ServerImpl initDestination

信息: Setting the server's publish address to be http://localhost:9000/helloWorld

2011-03-17 10:17:25.375:INFO::jetty-7.2.2.v20101205

2011-03-17 10:17:25.468:INFO::Started SelectChannelConnector@localhost:9000

server ready ……

 

那么你在WebBrowser中请求:

http://localhost:9000/helloWorld?wsdl就可以看到xml内容了。

3、  定制客户端调用WebService的接口,这个接口中的方法签名和参数信息可以从wsdl中的内容看到,代码如下:

package com.hoo.service;

 

import javax.jws.WebParam;

import javax.jws.WebService;

 

/**

 * <b>function:</b>客户端调用WebService所需要的接口

 * @authorhoojo

 * @createDate 2011-3-17上午09:00:00

 * @file IHelloWorldService.java

 * @package com.hoo.service

 * @project CXFWebService

 * @blog http://blog.csdn.net/IBM_hoojo

 * @email hoojo_@126.com

 * @version 1.0

 */

@WebService

publicinterface IHelloWorldService {

    public String sayHello(@WebParam(name ="name") String name);

}

 

4、  编写客户端调用WebService代码

package com.hoo.client;

 

import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;

import com.hoo.service.IHelloWorldService;

 

/**

 * <b>function:</b>CXF WebService客户端调用代码

 * @authorhoojo

 * @createDate 2011-3-16上午09:03:49

 * @file HelloWorldServiceClient.java

 * @package com.hoo.client

 * @project CXFWebService

 * @blog http://blog.csdn.net/IBM_hoojo

 * @email hoojo_@126.com

 * @version 1.0

 */

publicclass HelloWorldServiceClient {

   

    publicstaticvoid main(String[] args) {

       //调用WebService

       JaxWsProxyFactoryBean factory =new JaxWsProxyFactoryBean();

       factory.setServiceClass(IHelloWorldService.class);

       factory.setAddress("http://localhost:9000/helloWorld");

      

       IHelloWorldService service = (IHelloWorldService) factory.create();

       System.out.println("[result]" + service.sayHello("hoojo"));

    }

}

运行上面的程序后,结果如下:

2011-3-17 10:23:34 org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromClass

信息: Creating Service {http://service.hoo.com/}IHelloWorldServiceService from class com.hoo.service.IHelloWorldService

[result]hoojo say: Hello World

 

三、 CXF对Interceptor拦截器的支持

前面在Axis中介绍过Axis的Handler,这里CXF的Interceptor就和Handler的功能类似。在每个请求响应之前或响应之后,做一些事情。这里的Interceptor就和Filter、Struts的Interceptor很类似,提供它的主要作用就是为了很好的降低代码的耦合性,提供代码的内聚性。下面我们就看看CXF的Interceptor是怎么样工作的。

1、  我们就用上面的HelloWorldService,客户端的调用代码重新写一份,代码如下:

package com.hoo.client;

 

import org.apache.cxf.interceptor.LoggingInInterceptor;

import org.apache.cxf.interceptor.LoggingOutInterceptor;

import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;

import org.apache.cxf.phase.Phase;

import com.hoo.interceptor.MessageInterceptor;

import com.hoo.service.IHelloWorldService;

 

/**

 * <b>function:</b>CXF WebService客户端调用代码

 * @authorhoojo

 * @createDate 2011-3-16上午09:03:49

 * @file HelloWorldServiceClient.java

 * @package com.hoo.client

 * @project CXFWebService

 * @blog http://blog.csdn.net/IBM_hoojo

 * @email hoojo_@126.com

 * @version 1.0

 */

publicclass ServiceMessageInterceperClient {

   

    publicstaticvoid main(String[] args) {

       //调用WebService

       JaxWsProxyFactoryBean factory =new JaxWsProxyFactoryBean();

       factory.setServiceClass(IHelloWorldService.class);

       factory.setAddress("http://localhost:9000/helloWorld");

       factory.getInInterceptors().add(new LoggingInInterceptor());

       factory.getOutInterceptors().add(new LoggingOutInterceptor());

      

       IHelloWorldService service = (IHelloWorldService) factory.create();

       System.out.println("[result]" + service.sayHello("hoojo"));

    }

}

上面的CXF的拦截器是添加在客户端,同样在服务器端也是可以添加拦截器Interceptor的。运行后结果如下:

2011-3-18 7:34:00 org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromClass

信息: Creating Service {http://service.hoo.com/}IHelloWorldServiceService from class com.hoo.service.IHelloWorldService

2011-3-18 7:34:00 org.apache.cxf.interceptor.AbstractLoggingInterceptor log

信息: Outbound Message

---------------------------

ID: 1

Address: http://localhost:9000/helloWorld

Encoding: UTF-8

Content-Type: text/xml

Headers: {SOAPAction=[""], Accept=[*/*]}

Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns1:sayHello xmlns:ns1="http://service.hoo.com/"><name>hoojo</name></ns1:sayHello></soap:Body></soap:Envelope>

--------------------------------------

2011-3-18 7:34:01 org.apache.cxf.interceptor.AbstractLoggingInterceptor log

信息: Inbound Message

----------------------------

ID: 1

Response-Code: 200

Encoding: UTF-8

Content-Type: text/xml;charset=UTF-8

Headers: {content-type=[text/xml;charset=UTF-8], Content-Length=[230], Server=[Jetty(7.2.2.v20101205)]}

Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns1:sayHelloResponse xmlns:ns1="http://service.hoo.com/"><return>hoojo say: Hello World </return></ns1:sayHelloResponse></soap:Body></soap:Envelope>

--------------------------------------

[result]hoojo say: Hello World

上面的部分信息是LoggingInterceptor输出的日志信息,分别在请求和响应的时候输出日志信息,还有输出请求的时候参数的信息以及响应的时候返回值的信息。

2、  刚才是客户端添加Interceptor,现在我们自己编写一个Interceptor,这个Interceptor需要继承AbstractPhaseInterceptor,实现handleMessage和一个带参数的构造函数。然后在服务器端添加这个Interceptor。

Interceptor代码如下:

package com.hoo.interceptor;

 

import org.apache.cxf.interceptor.Fault;

import org.apache.cxf.message.Message;

import org.apache.cxf.phase.AbstractPhaseInterceptor;

 

/**

 * <b>function:</b>自定义消息拦截器

 * @authorhoojo

 * @createDate Mar 17, 2011 8:10:49 PM

 * @file MessageInterceptor.java

 * @package com.hoo.interceptor

 * @project CXFWebService

 * @blog http://blog.csdn.net/IBM_hoojo

 * @email hoojo_@126.com

 * @version 1.0

 */

publicclass MessageInterceptorextends AbstractPhaseInterceptor<Message> {

   

    //至少要一个带参的构造函数

    public MessageInterceptor(String phase) {

       super(phase);

    }

 

    publicvoid handleMessage(Message message)throws Fault {

       System.out.println("############handleMessage##########");

       System.out.println(message);

       if (message.getDestination() !=null) {

           System.out.println(message.getId() +"#" + message.getDestination().getMessageObserver());

       }

       if (message.getExchange() !=null) {

           System.out.println(message.getExchange().getInMessage() +"#" + message.getExchange().getInFaultMessage());

           System.out.println(message.getExchange().getOutMessage() +"#" + message.getExchange().getOutFaultMessage());

       }

    }

}

下面看看发布服务和添加自定义拦截器的代码:

package com.hoo.service.deploy;

 

import org.apache.cxf.jaxws.JaxWsServerFactoryBean;

import org.apache.cxf.phase.Phase;

import com.hoo.interceptor.MessageInterceptor;

import com.hoo.service.HelloWorldService;

 

/**

 * <b>function:</b>在服务器发布自定义的Interceptor

 * @authorhoojo

 * @createDate 2011-3-18上午07:38:28

 * @file DeployInterceptorService.java

 * @package com.hoo.service.deploy

 * @project CXFWebService

 * @blog http://blog.csdn.net/IBM_hoojo

 * @email hoojo_@126.com

 * @version 1.0

 */

publicclass DeployInterceptorService {

 

    publicstaticvoid main(String[] args)throws InterruptedException {

       //发布WebService

       JaxWsServerFactoryBean factory =new JaxWsServerFactoryBean();

       //设置Service Class

       factory.setServiceClass(HelloWorldService.class);

       factory.setAddress("http://localhost:9000/helloWorld");

       //设置ServiceBean对象

       factory.setServiceBean(new HelloWorldService());

      

       //添加请求和响应的拦截器,Phase.RECEIVE只对In有效,Phase.SEND只对Out有效

       factory.getInInterceptors().add(new MessageInterceptor(Phase.RECEIVE));

       factory.getOutInterceptors().add(new MessageInterceptor(Phase.SEND));

      

       factory.create();

      

       System.out.println("Server start ......");

       Thread.sleep(1000 * 60);

       System.exit(0);

       System.out.println("Server exit ");

    }

}

值得说的是,以前发布WebService是用Endpoint的push方法。这里用的是JaxWsServerFactoryBean和客户端调用的代码JaxWsProxyFactoryBean有点不同

客户端调用代码:

package com.hoo.client;

 

import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;

import com.hoo.service.IHelloWorldService;

 

/**

 * <b>function:</b>CXF WebService客户端调用代码

 * @authorhoojo

 * @createDate 2011-3-16上午09:03:49

 * @file HelloWorldServiceClient.java

 * @package com.hoo.client

 * @project CXFWebService

 * @blog http://blog.csdn.net/IBM_hoojo

 * @email hoojo_@126.com

 * @version 1.0

 */

publicclass HelloWorldServiceClient {

   

    publicstaticvoid main(String[] args) {

       //调用WebService

       JaxWsProxyFactoryBean factory =new JaxWsProxyFactoryBean();

       factory.setServiceClass(IHelloWorldService.class);

       factory.setAddress("http://localhost:9000/helloWorld");

      

       IHelloWorldService service = (IHelloWorldService) factory.create();

       System.out.println("[result]" + service.sayHello("hoojo"));

    }

}

 

四、 传递复杂类型对象

前面介绍的都是传递简单的字符串,现在开始介绍传递复杂类型的对象。如JavaBean、Array、List、Map等。

1、  首先看看服务器端的代码所需要的JavaBean对象

package com.hoo.entity;

 

import java.io.Serializable;

 

/**

 * <b>function:</b>User Entity

 * @authorhoojo

 * @createDateDec 16, 2010 10:20:02 PM

 * @file User.java

 * @package com.hoo.entity

 * @project AxisWebService

 * @blog http://blog.csdn.net/IBM_hoojo

 * @email hoojo_@126.com

 * @version 1.0

 */

publicclass Userimplements Serializable {

    privatestaticfinallongserialVersionUID = 677484458789332877L;

    privateintid;

    private Stringname;

    private Stringemail;

    private Stringaddress;

   

    //gettersetter

   

    @Override

    public String toString() {

       returnthis.id +"#" + this.name +"#" + this.email +"#" + this.address;

    }

}

下面的是集合传递Users,CXF直接传递集合对象会出现异常,用一个对象包装下就Ok了,不知道是什么原因。异常信息如下:

DefaultValidationEventHandler: [ERROR]: unexpected element(uri:"", local:"item")

org.apache.cxf.interceptor.Fault: Unmarshalling Error: unexpected element (uri:"", local:"item")

 

package com.hoo.entity;

 

import java.util.HashMap;

import java.util.List;

 

/**

 * <b>function:</b> Users Entity

 * @authorhoojo

 * @createDate 2011-3-18上午09:27:31

 * @file Users.java

 * @package com.hoo.entity

 * @project CXFWebService

 * @blog http://blog.csdn.net/IBM_hoojo

 * @email hoojo_@126.com

 * @version 1.0

 */

publicclass Users {

    private List<User>users;

    private User[]userArr;

    private HashMap<String, User>maps;

      

    //gettersetter方法

}

 

2、  下面看看复杂对象传递的服务器端代码

package com.hoo.service;

 

import java.util.ArrayList;

import java.util.Date;

import java.util.HashMap;

import java.util.List;

import javax.jws.WebParam;

import javax.jws.WebService;

import javax.jws.soap.SOAPBinding;

import javax.jws.soap.SOAPBinding.Style;

import com.hoo.entity.User;

import com.hoo.entity.Users;

 

/**

 * <b>function:</b> WebService传递复杂对象,如JavaBeanArrayListMap

 * @authorhoojo

 * @createDate 2011-3-18上午08:22:55

 * @file ComplexUserService.java

 * @package com.hoo.service

 * @project CXFWebService

 * @blog http://blog.csdn.net/IBM_hoojo

 * @email hoojo_@126.com

 * @version 1.0

 */

@WebService

@SOAPBinding(style = Style.RPC)

@SuppressWarnings("deprecation")

publicclass ComplexUserService {

   

    public User getUserByName(@WebParam(name ="name") String name) {

       User user = new User();

       user.setId(new Date().getSeconds());

       user.setName(name);

       user.setAddress("china");

       user.setEmail(name + "@hoo.com");

       return user;

    }

   

    publicvoid setUser(User user) {

       System.out.println("############Server setUser###########");

       System.out.println("setUser:" + user);

    }

   

    public Users getUsers(int i) {

       List<User> users = new ArrayList<User>();

       for (int j = 0; j <= i; j++) {

           User user = new User();

           user.setId(new Date().getSeconds());

           user.setName("jack#" + j);

           user.setAddress("china");

           user.setEmail("jack" + j +"@hoo.com");

           users.add(user);

       }

       Users u = new Users();

       u.setUsers(users);

       return u;

    }

   

    publicvoid setUsers(Users users) {

       System.out.println("############Server setUsers###########");

       for (User u : users.getUsers()) {

           System.out.println("setUsers:" + u);

       }

    }

   

    public Users getUserArray(int i) {

       User[] users = new User[i];

       for (int j = 0; j < i; j++) {

           User user = new User();

           user.setId(new Date().getSeconds());

           user.setName("jack#" + j);

           user.setAddress("china");

           user.setEmail("jack" + j +"@hoo.com");

           users[j] = user;

       }

       Users u = new Users();

       u.setUserArr(users);

       return u;

    }

   

    publicvoid setUserArray(Users users) {

       System.out.println("############Server setUserArray###########");

       for (User u : users.getUserArr()) {

           System.out.println("setUserArray:" + u);

       }

    }

   

    publicvoid setUserMap(Users maps) {

       System.out.println("############Server setUserMap###########");

       System.out.println("setUserMap:" + maps.getMaps());

    }

   

    public Users getUserMap() {

       HashMap<String, User> users =new HashMap<String, User>();

       User user = new User();

       user.setId(new Date().getSeconds());

       user.setName("jack#");

       user.setAddress("china#");

       user.setEmail("jack@hoo.com");

       users.put("A", user);

      

       user = new User();

       user.setId(new Date().getSeconds());

       user.setName("tom");

       user.setAddress("china$$");

       user.setEmail("tom@hoo.com");

       users.put("B", user);

       Users u = new Users();

       u.setMaps(users);

      

       return u;

    }

}

3、  发布WebService的代码

package com.hoo.service.deploy;

 

import com.hoo.service.ComplexUserService;

 

/**

 * <b>function:</b>发布ComplexUserService服务

 * @authorhoojo

 * @createDate 2011-3-18上午08:28:57

 * @file DeployComplexUserService.java

 * @package com.hoo.service.deploy

 * @project CXFWebService

 * @blog http://blog.csdn.net/IBM_hoojo

 * @email hoojo_@126.com

 * @version 1.0

 */

publicclass DeployComplexUserService {

 

    publicstaticvoid main(String[] args)throws InterruptedException {

       String address = "http://localhost:9000/complexUser";

       DeployUtils.deployService(address,new ComplexUserService());

       Thread.sleep(1000 * 60 * 20);

       System.exit(0);

       System.out.println("Server exit ");

    }

}

4、  通过发布后的地址的http://localhost:9000/complexUser?wsdl; wsdl中的内容定制你的客户端调用WebService的接口,当然你也可以让服务器端实现一个接口。

package com.hoo.service;

 

import javax.jws.WebParam;

import javax.jws.WebService;

import com.hoo.entity.User;

import com.hoo.entity.Users;

 

/**

 * <b>function:</b>定制客户端请求WebService所需要的接口

 * @authorhoojo

 * @createDate 2011-3-18上午08:22:55

 * @file ComplexUserService.java

 * @package com.hoo.service

 * @project CXFWebService

 * @blog http://blog.csdn.net/IBM_hoojo

 * @email hoojo_@126.com

 * @version 1.0

 */

@WebService

publicinterface IComplexUserService {

   

    public User getUserByName(@WebParam(name ="name") String name);

   

    publicvoid setUser(User user);

   

    public Users getUsers(int i);

   

    publicvoid setUsers(Users users);

   

    public Users getUserArray(int i);

   

    publicvoid setUserArray(Users users);

   

    publicvoid setUserMap(Users maps);

   

    public Users getUserMap();

}

5、  客户端调用代码

package com.hoo.client;

 

import java.util.ArrayList;

import java.util.List;

import java.util.Random;

import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;

import com.hoo.entity.User;

import com.hoo.entity.Users;

import com.hoo.service.IComplexUserService;

 

/**

 * <b>function:</b>调用ComplexUserService客户端

 * @authorhoojo

 * @createDate 2011-3-18上午08:37:11

 * @file ComplexUserServiceClient.java

 * @package com.hoo.client

 * @project CXFWebService

 * @blog http://blog.csdn.net/IBM_hoojo

 * @email hoojo_@126.com

 * @version 1.0

 */

publicclass ComplexUserServiceClient {

 

    publicstaticvoid main(String[] args) {

       //调用WebService

       JaxWsProxyFactoryBean factory =new JaxWsProxyFactoryBean();

       factory.setServiceClass(IComplexUserService.class);

       factory.setAddress("http://localhost:9000/complexUser");

      

       IComplexUserService service = (IComplexUserService) factory.create();

      

       System.out.println("#############Client getUserByName##############");

       User user = service.getUserByName("hoojo");

       System.out.println(user);

      

       user.setAddress("China-Guangzhou");

       service.setUser(user);

      

       System.out.println("#############Client getUsers##############");

       Users users = service.getUsers(4);

       System.out.println(users);

       List<User> tempUsers = new ArrayList<User>();

       for (User u : users.getUsers()) {

           System.out.println(u);

           u.setName("hoojo" +new Random().nextInt(100));

           u.setAddress("Chian-GuangZhou#" +new Random().nextInt(100));

           tempUsers.add(u);

       }

       users.getUsers().clear();

       users.getUsers().addAll(tempUsers);

       service.setUsers(users);

      

       System.out.println("#############Client getUserArray##############");

       users = service.getUserArray(4);

       User[] userArr = new User[4];

       int i = 0;

       for (User u : users.getUserArr()) {

           System.out.println(u);

           u.setName("hoojo" +new Random().nextInt(100));

           u.setAddress("Chian-ShenZhen#" +new Random().nextInt(100));

           userArr[i] = u;

           i ++;

       }

      

       users.setUserArr(userArr);

       service.setUserArray(users);

      

       System.out.println("##################Client getUserMap###############");

       users = service.getUserMap();

       System.out.println(users.getMaps());

       users.getMaps().put("ABA", userArr[0]);

       service.setUserMap(users);

    }

}

 

6、  运行后结果如下

控制台客户端结果:

2011-3-18 10:31:11 org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromClass

信息: Creating Service {http://service.hoo.com/}IComplexUserServiceService from class com.hoo.service.IComplexUserService

#############Client getUserByName##############

12#hoojo#hoojo@hoo.com#china

#############Client getUsers##############

com.hoo.entity.Users@1148603

12#jack#0#jack0@hoo.com#china

12#jack#1#jack1@hoo.com#china

12#jack#2#jack2@hoo.com#china

12#jack#3#jack3@hoo.com#china

12#jack#4#jack4@hoo.com#china

#############Client getUserArray##############

12#jack#0#jack0@hoo.com#china

12#jack#1#jack1@hoo.com#china

12#jack#2#jack2@hoo.com#china

12#jack#3#jack3@hoo.com#china

##################Client getUserMap###############

{A=12#jack##jack@hoo.com#china#, B=12#tom#tom@hoo.com#china$$}

服务器端结果:

Server start ……

2011-3-18 10:31:03 org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromClass

信息: Creating Service {http://service.hoo.com/}ComplexUserServiceService from class com.hoo.service.ComplexUserService

2011-3-18 10:31:03 org.apache.cxf.endpoint.ServerImpl initDestination

信息: Setting the server's publish address to be http://localhost:9000/complexUser

2011-03-18 10:31:03.906:INFO::jetty-7.2.2.v20101205

2011-03-18 10:31:04.046:INFO::Started SelectChannelConnector@localhost:9000

############Server setUser###########

setUser:12#hoojo#hoojo@hoo.com#China-Guangzhou

############Server setUsers###########

setUsers:12#hoojo67#jack0@hoo.com#Chian-GuangZhou#94

setUsers:12#hoojo95#jack1@hoo.com#Chian-GuangZhou#27

setUsers:12#hoojo29#jack2@hoo.com#Chian-GuangZhou#0

setUsers:12#hoojo94#jack3@hoo.com#Chian-GuangZhou#70

setUsers:12#hoojo49#jack4@hoo.com#Chian-GuangZhou#92

############Server setUserArray###########

setUserArray:12#hoojo24#jack0@hoo.com#Chian-ShenZhen#30

setUserArray:12#hoojo57#jack1@hoo.com#Chian-ShenZhen#81

setUserArray:12#hoojo84#jack2@hoo.com#Chian-ShenZhen#41

setUserArray:12#hoojo88#jack3@hoo.com#Chian-ShenZhen#79

############Server setUserMap###########

setUserMap:{ABA=12#hoojo24#jack0@hoo.com#Chian-ShenZhen#30, A=12#jack##jack@hoo.com#china#, B=12#tom#tom@hoo.com#china$$}

五、 CXF整合Spring

首先,CXF和spring整合需要准备如下jar包文件:

这边我是用Spring的jar包是Spring官方提供的,并没有使用CXF中的Spring的jar文件。

添加这么多文件后,首先在web.xml中添加如下配置:

<!-- 加载Spring容器配置 -->

<listener>

    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>

<!-- 设置Spring容器加载配置文件路径 -->

<context-param>

    <param-name>contextConfigLocation</param-name>

    <param-value>classpath*:applicationContext-server.xml</param-value>

</context-param>

 

<listener>

    <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>

</listener>

 

<servlet>

    <servlet-name>CXFService</servlet-name>

    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>

</servlet>

 

<servlet-mapping>

    <servlet-name>CXFService</servlet-name>

    <url-pattern>/*</url-pattern>

</servlet-mapping>

然后在src目录中,新建一个applicationContext-server.xml文件,文件内容如下:

<?xmlversion="1.0"encoding="UTF-8"?>

<beansxmlns="http://www.springframework.org/schema/beans"

    xmlns:context="http://www.springframework.org/schema/context"

    xmlns:jaxws="http://cxf.apache.org/jaxws"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xsi:schemaLocation="http://www.springframework.org/schema/beans

    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

    http://www.springframework.org/schema/context

    http://www.springframework.org/schema/context/spring-context-3.0.xsd

    http://cxf.apache.org/jaxws

    http://cxf.apache.org/schemas/jaxws.xsd">

注意上面的黄色背景部分,这个很重要的哦!

添加完这个文件后,还需要在这个文件中导入这么几个文件。文件内容如下:

<importresource="classpath:META-INF/cxf/cxf.xml"/>

<importresource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>

<import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>

下面开始写服务器端代码,首先定制服务器端的接口,代码如下:

package com.hoo.service;

 

import javax.jws.WebParam;

import javax.jws.WebService;

import javax.jws.soap.SOAPBinding;

import javax.jws.soap.SOAPBinding.Style;

import com.hoo.entity.User;

import com.hoo.entity.Users;

 

/**

 * <b>function:</b>定制客户端请求WebService所需要的接口

 * @authorhoojo

 * @createDate 2011-3-18上午08:22:55

 * @file ComplexUserService.java

 * @package com.hoo.service

 * @project CXFWebService

 * @blog http://blog.csdn.net/IBM_hoojo

 * @email hoojo_@126.com

 * @version 1.0

 */

@WebService

@SOAPBinding(style = Style.RPC)

publicinterface IComplexUserService {

   

    public User getUserByName(@WebParam(name ="name") String name);

   

    publicvoid setUser(User user);

}

下面编写WebService的实现类,服务器端实现代码如下:

package com.hoo.service;

 

import java.util.ArrayList;

import java.util.Date;

import java.util.HashMap;

import java.util.List;

import javax.jws.WebParam;

import javax.jws.WebService;

import javax.jws.soap.SOAPBinding;

import javax.jws.soap.SOAPBinding.Style;

import com.hoo.entity.User;

import com.hoo.entity.Users;

 

/**

 * <b>function:</b> WebService传递复杂对象,如JavaBeanArrayListMap

 * @authorhoojo

 * @createDate 2011-3-18上午08:22:55

 * @file ComplexUserService.java

 * @package com.hoo.service

 * @project CXFWebService

 * @blog http://blog.csdn.net/IBM_hoojo

 * @email hoojo_@126.com

 * @version 1.0

 */

@WebService

@SOAPBinding(style = Style.RPC)

@SuppressWarnings("deprecation")

publicclass ComplexUserServiceimplements IComplexUserService {

   

    public User getUserByName(@WebParam(name ="name") String name) {

       User user = new User();

       user.setId(new Date().getSeconds());

       user.setName(name);

       user.setAddress("china");

       user.setEmail(name + "@hoo.com");

       return user;

    }

   

    publicvoid setUser(User user) {

       System.out.println("############Server setUser###########");

       System.out.println("setUser:" + user);

    }

}

注意的是和Spring集成,这里一定要完成接口实现,如果没有接口的话会有错误的。

下面要在applicationContext-server.xml文件中添加如下配置:

<beanid="userServiceBean"class="com.hoo.service.ComplexUserService"/>

 

<beanid="inMessageInterceptor"class="com.hoo.interceptor.MessageInterceptor">

    <constructor-arg value="receive"/>

</bean>

 

<beanid="outLoggingInterceptor"class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>

//注意下面的address,这里的address的名称就是访问的WebService的name

<jaxws:serverid="userService"serviceClass="com.hoo.service.IComplexUserService"address="/Users">

    <jaxws:serviceBean>

       <!--要暴露的 bean 的引用 -->

       <refbean="userServiceBean"/>

    </jaxws:serviceBean>

    <jaxws:inInterceptors>

       <refbean="inMessageInterceptor"/>

    </jaxws:inInterceptors>

    <jaxws:outInterceptors>

       <refbean="outLoggingInterceptor"/>

    </jaxws:outInterceptors>

</jaxws:server>

下面启动tomcat服务器后,在WebBrowser中请求:

http://localhost:8080/CXFWebService/Users?wsdl

如果你能看到wsdl的xml文件的内容,就说明你成功了,注意的是上面地址的Users就是上面xml配置中的address的名称,是一一对应的。

下面编写客户端请求的代码,代码如下:

package com.hoo.client;

 

import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;

import com.hoo.entity.User;

import com.hoo.service.IComplexUserService;

 

/**

 * <b>function:</b>请求Spring整合CXFWebService客户端

 * @authorhoojo

 * @createDate 2011-3-28下午03:20:35

 * @file SpringUsersWsClient.java

 * @package com.hoo.client

 * @project CXFWebService

 * @blog http://blog.csdn.net/IBM_hoojo

 * @email hoojo_@126.com

 * @version 1.0

 */

publicclass SpringUsersWsClient {

 

    publicstaticvoid main(String[] args) {

       //调用WebService

       JaxWsProxyFactoryBean factory =new JaxWsProxyFactoryBean();

       factory.setServiceClass(IComplexUserService.class);

        factory.setAddress("http://localhost:8080/CXFWebService/Users");

      

       IComplexUserService service = (IComplexUserService) factory.create();

      

       System.out.println("#############Client getUserByName##############");

       User user = service.getUserByName("hoojo");

       System.out.println(user);

      

       user.setAddress("China-Guangzhou");

       service.setUser(user);

    }

}

运行后,可以在控制台中看到

log4j:WARN No appenders could be found for logger (org.apache.cxf.bus.spring.BusApplicationContext).

log4j:WARN Please initialize the log4j system properly.

log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

2011-3-28 18:12:26 org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromClass

信息: Creating Service {http://service.hoo.com/}IComplexUserServiceService from class com.hoo.service.IComplexUserService

#############Client getUserByName##############

27#hoojo#hoojo@hoo.com#china

 

Tomcat控制台

这个server端是通过Spring整合配置的,下面我们将Client端也通过Spring配置完成整合。

首先增加applicationContext-client.xml配置文件,文件内容如下:

<?xmlversion="1.0"encoding="UTF-8"?>

<beansxmlns="http://www.springframework.org/schema/beans"

    xmlns:context="http://www.springframework.org/schema/context"

    xmlns:jaxws="http://cxf.apache.org/jaxws"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xsi:schemaLocation="http://www.springframework.org/schema/beans

    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

    http://www.springframework.org/schema/context

    http://www.springframework.org/schema/context/spring-context-3.0.xsd

    http://cxf.apache.org/jaxws

    http://cxf.apache.org/schemas/jaxws.xsd">

   

    <importresource="classpath:META-INF/cxf/cxf.xml"/>

    <importresource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>

    <importresource="classpath:META-INF/cxf/cxf-servlet.xml"/>

   

    <jaxws:clientid="userWsClient"serviceClass="com.hoo.service.IComplexUserService"

       address="http://localhost:8080/CXFWebService/Users"/>

</beans>

客户端请求代码如下:

package com.hoo.client;

 

importorg.apache.cxf.jaxws.JaxWsProxyFactoryBean;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

 

import com.hoo.entity.User;

import com.hoo.service.IComplexUserService;

 

/**

 * <b>function:</b>请求Spring整合CXFWebService客户端

 * @authorhoojo

 * @createDate 2011-3-28下午03:20:35

 * @file SpringUsersWsClient.java

 * @package com.hoo.client

 * @project CXFWebService

 * @blog http://blog.csdn.net/IBM_hoojo

 * @email hoojo_@126.com

 * @version 1.0

 */

publicclass SpringUsersWsClient {

 

    publicstaticvoid main(String[] args) {

       ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-client.xml");

      

       IComplexUserService service =ctx.getBean("userWsClient", IComplexUserService.class);

      

       System.out.println("#############Client getUserByName##############");

       User user = service.getUserByName("hoojo");

       System.out.println(user);

      

       user.setAddress("China-Guangzhou");

       service.setUser(user);

    }

}

运行后结果如下:

#############Client getUserByName##############

45#hoojo#hoojo@hoo.com#china

############Server setUser###########

setUser:45#hoojo#hoojo@hoo.com#China-Guangzhou

 

原创粉丝点击