一、基本类型,包括int,String等基本类型
1. 下载xfire-all.jar和其依赖包,放到classpath下。
2. 新建一个工程HelloWebService(我用的是MyEclipse6.0+Tomcat5.5,注意尽量不要用MyEclipse自带的“创建WebService工程”功能)。
3. 创建一个Interface ,名称是IHelloService,其内容如下:
package com.lawrenst.service; public interface IHelloService{ public String sayHello(String name); }
并创建其实现类,HelloServiceImpl,内容如下,
package com.lawrenst.service; public class HelloServiceImplimplements IHelloService{ public String sayHello(String name) { return "Hello "+name; } }
由于代码比较简单,就不写注释了。
4. 在src下建立一个文件夹,META-INF(注意大小写),在META-INF下建立一个xfire文件夹,在xfire中建立services.xml文件。(真啰嗦),其内容如下:
<beans xmlns="http://xfire.codehaus.org/config/1.0"> <service> <name>HelloService</name> <!-- <namespace>http://oe-way.com/BookService</namespace> --> <!-- 接口--> <serviceClass>com.lawrenst.service.IHelloService</serviceClass> <!-- 接口的实现类--> <implementationClass>test.risesoft.BookServiceImpl</implementationClass> <properties> <property key="mtom-enabled">true</property> </properties> <style>wrapped</style> <use>literal</use> <scope>application</scope> </service> </beans>
5. 在web.xml中配置上xfire
<servlet> <servlet-name>XFireServlet</servlet-name> <servlet-class> org.codehaus.xfire.transport.http.XFireConfigurableServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>XFireServlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping>
6. 访问 http://localhost:8080/HelloWebService/services/HelloService?wsdl
好了页面出现了,至此,你的第一个WebService发布成功了。
7. 编写客户端程序
在这里,我介绍两种方式,第一种是纯POJO方式,第二种是动态方式
第一种:纯POJO方式
package com.lawrenst.test; import java.net.MalformedURLException; import org.codehaus.xfire.XFireFactory; import org.codehaus.xfire.client.XFireProxyFactory; import org.codehaus.xfire.service.Service; import org.codehaus.xfire.service.binding.ObjectServiceFactory; import com.lawrenst.service.IHelloService; public class TestClient { public static void main(String args[]){ Service serviceModel=new ObjectServiceFactory().create(IHelloService.class); XFireProxyFactory factory = new XFireProxyFactory(XFireFactory.newInstance().getXFire()); String url="http://localhost:8080/HelloWebService/services/HelloService"; try { IHelloService service=(IHelloService) factory.create(serviceModel, url); //测试sayHello方法 System.out.println(service.sayHello("lawrenst")); } catch (MalformedURLException e) { e.printStackTrace(); } } }
ok,看看你的控制台,是不是出现了预期的东西。
第二种:动态方式(动态模式不需要服务端的class,不过性能和复杂对象映射等估计做得不会太好。)
Client client = new Client(new URL ("http://localhost;8080/HelloWebService/services/HelloService?WSDL")); Object[] results = client.invoke("sayHello", new Object[] {"lawrenst"}); System.out.println(results[0]);
二、复杂类型的,包括返回值是List ,Map,以及自定义对象等
1. 在上次所建立的工程基础上,修改IHelloService,增加两个方法:
public Course choose(Student student) { System.out.println(student.getName()); Course course=new Course(); course.setCourseName("Computer Science"); return course; } public List test(List temp) { for(int i=0;i<temp.size();i++){ System.out.println(temp.get(i)); } List temp2=new ArrayList(); Course course1=new Course(); course1.setCourseName("English"); temp2.add(course1); Course course2=new Course(); course2.setCourseName("Art"); temp2.add(course2); return temp2; }
2. 建立两个类,内容分别如下:
package com.lawrenst.pojo; public class Course { private String courseName; public String getCourseName() { return courseName; } public void setCourseName(String courseName) { this.courseName = courseName; } } package com.lawrenst.pojo; public class Student{ private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
3. 启动服务器,并访问wsdl文件,出现了什么?出现了异常,大概是什么什么为空。
xfire默认是Aegis绑定,需要建立一个XXX.aegis.xml文件,让xfire知道test方法中的参数和返回对象是什么类型的。
建立IHelloService.aegis.xml,注意,必须是和接口名称相同,并且和IHelloService在相同目录下。内容如下:
<?xml version="1.0" encoding="UTF-8"?> <mappings> <mapping> <method name="test"> <parameter componentType="java.lang.String" /> <return-type componentType="com.lawrenst.pojo.Course" /> </method> </mapping> </mappings>
好了,重启服务器,wsdl文件能够正常显示了。
4. 同样建立客户端(这里我使用的是纯POJO方式,动态方式我没有找到解决的办法,如果哪位高手找到了解决的办法,可以给我留言)
package com.lawrenst.test; import java.net.MalformedURLException; import java.util.ArrayList; import java.util.List; import org.codehaus.xfire.XFireFactory; import org.codehaus.xfire.client.XFireProxyFactory; import org.codehaus.xfire.service.Service; import org.codehaus.xfire.service.binding.ObjectServiceFactory; import com.lawrenst.pojo.Course; import com.lawrenst.pojo.Student; import com.lawrenst.service.IHelloService; public class TestClient { public static void main(String args[]) { Service serviceModel = new ObjectServiceFactory() .create(IHelloService.class); XFireProxyFactory factory = new XFireProxyFactory(XFireFactory .newInstance().getXFire()); String url = "http://localhost:8080/Xfire/services/HelloService"; try { IHelloService service = (IHelloService) factory.create( serviceModel, url); // 测试sayHello方法 System.out.println(service.sayHello("lawrenst")); // 测试choose方法 Student student = new Student(); student.setName("jijingping"); Course course = service.choose(student); System.out.println(course.getCourseName()); // 测试test方法 List temp = new ArrayList();// 给test方法传递的参数 temp.add("wangxiaosen"); temp.add("wangxinlei"); temp.add("wangye"); List t = service.test(temp); for (int i = 0; i < t.size(); i++) { Course c = t.get(i); System.out.println(c.getCourseName()); } } catch (MalformedURLException e) { e.printStackTrace(); } } }
好了 再次成功了,看看服务器端和客户端是不是打印出了相应的东西?
通过上两次的介绍,相信大家对xfire有了一个初步的了解,这里还有一个问题,上两次内容都是基于jdk1.4的,如果想用jdk1.5或是使用了泛型,比如
List<Course> test(List<String> temp),在编译期就已经知道了相应的参数以及返回值的类型,那么就不需要再用Aegis绑定了。(当然,象Collection之类的是无法使用泛型的,因为你根本不知道里面放的是什么)
1. 修改接口内容及其测试类:
public List<Course> test(List<String> t); public List<Course> test(List<String> t) { for (int i = 0; i < t.size(); i++) { System.out.println(t.get(i)); } List<Course> temp = new ArrayList<Course>(); Course course1 = new Course(); course1.setCourseName("English"); temp.add(course1); Course course2 = new Course(); course2.setCourseName("Art"); temp.add(course2); return temp; }
因为使用了泛型,所以就不需要建立IHelloService.aegis.xml了。
重启服务器,运行客户端程序,看看是不是也成功了?