通过IDE开发基于web的XFire(WebService)
请下载两个工具包供环境使用 。
1、xfire-distribution-1.2.6.zip,主要包含XFire依赖的部分jar包,下载地址为distribution-1.2.6.zip;
2、xalan-j_2_7_1-bin.zip ,主要包含了处理XML的工具,其下载地址为http://apache.mirror.phpchina.com/xml/xalan-j/xalan-j_2_7_1-bin.zip
一.配置IDE环境与XFire的开发
1、新建一个Java工程,取名为XFireDemo,将xfire-distribution-1.2.6.zip中的xfire-all-1.2.6.jar和lib下面的所有包,还有 xalan-j_2_7_1-bin.zip中的 xalan.jar导入到IDE的类路径中(当然,可以为上述jar包创建一个用户类库)
2、如图1,在XFireDemo的src下新建包,java文件,文件夹,以及xml文件,其中,之所以将META-INF建立在src下,是为了将IDE编译后输出目录下的所有文件夹部署到Tomcat中。
3、所有代码:
Book.java 是数据的封装类
Book.java 源代码:
1. packagestoneyang.bean;
2.
3. publicclassBook{
4.
5. private String name;
6.
7. private String author;
8.
9. private String year;
10.
11. private String price;
12.
13. public String getName() {
14.
15. return name;
16.
17. }
18.
19. public void setName(String name) {
20.
21. this.name = name;
22.
23. }
24.
25. public String getAuthor() {
26.
27. return author;
28.
29. }
30.
31. public void setAuthor(String author) {
32.
33. this.author = author;
34.
35. }
36.
37. public String getYear() {
38.
39. return year;
40.
41. }
42.
43. public void setYear(String year) {
44.
45. this.year = year;
46.
47. }
48.
49. public String getPrice() {
50.
51. return price;
52.
53. }
54.
55. public void setPrice(String price) {
56.
57. this.price = price;
58.
59. }
60.
61. public Book() {
62.
63. super();
64.
65. }
66.
67. public Book(String name, String author, String year, String price) {
68.
69. super();
70.
71. this.name = name;
72.
73. this.author = author;
74.
75. this.year = year;
76.
77. this.price = price;
78.
79. }
80.
81. public Book(String name) {
82.
83. super();
84.
85. this.name = name;
86.
87. }
88.
89. public Book(String name, String year) {
90.
91. super();
92.
93. this.name = name;
94.
95. this.year = year;
96.
97. }
98.
99. public String toString(){
100.
101. StringBuilder builder = new StringBuilder();
102.
103. if( name != null && !"".equals(name.trim())){
104.
105. builder.append( " 名称: "+name );
106.
107. }
108.
109. if( author != null && !"".equals(author.trim())){
110.
111. builder.append( " 作者: "+author );
112.
113. }
114.
115. if( year != null && !"".equals(year.trim())){
116.
117. builder.append( " 年份: "+year );
118.
119. }
120.
121. if( price != null && !"".equals(price.trim())){
122.
123. builder.append( " 价格: "+price );
124.
125. }
126.
127. return builder.toString();
128.
129. }
130.
131. }
package stoneyang.bean; public class Book { private String name; private String author; private String year; private String price; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getYear() { return year; } public void setYear(String year) { this.year = year; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } public Book() { super(); } public Book(String name, String author, String year, String price) { super(); this.name = name; this.author = author; this.year = year; this.price = price; } public Book(String name) { super(); this.name = name; } public Book(String name, String year) { super(); this.name = name; this.year = year; } public String toString(){ StringBuilder builder = new StringBuilder(); if( name != null && !"".equals(name.trim())){ builder.append( " 名称: "+name ); } if( author != null && !"".equals(author.trim())){ builder.append( " 作者: "+author ); } if( year != null && !"".equals(year.trim())){ builder.append( " 年份: "+year ); } if( price != null && !"".equals(price.trim())){ builder.append( " 价格: "+price ); } return builder.toString(); } }
BusinessI.java 提供给webservice的接口,这里的返回值之所以用到泛型,是为了避免手动配置 stoneyang.businessI 包下BusinessI.aegis.xml的文件(BusinessI.java与BusinessI.aegis.xml同包,而且文件名的第一个“.”前的名称必须一样),而导致出错,此例子因用的是泛型,固无需配置。
BusinessI.java 源代码:
1. package stoneyang.businessI;
2.
3. import java.util.List;
4.
5. import stoneyang.bean.Book;
6.
7.
8.
9. public interface BusinessI {
10.
11. public Book getBookByName(String name);
12.
13. public List<Book> getBooksByNames(String[] bookNames);
14.
15. public List<Book> getBooksWithSpecialYear(Book book);
16.
17. }
package stoneyang.businessI;import java.util.List; import stoneyang.bean.Book; public interface BusinessI { public Book getBookByName(String name); public List<Book> getBooksByNames(String[] bookNames); public List<Book> getBooksWithSpecialYear(Book book); }
若使用泛型,可跳过“====”之间的部分
=======================================================================
若不用泛型,则需要加BusinessI.aegis.xml文件,下面代码可以看出,"getBooksByNames"的方法的参数是字符串数组,但componentType="java.lang.String",返回的是集合,但componentType="stoneyang.bean.Book",可以看出,componentType会自动将参数(无论是集合还是数组或者是自定义类型)都会取一个尝试转换成配置的类型,而不是将String[],List来强转成componentType指定的类型;下面代码不能够写成两个map,每个map有一个method,那么程序会报错。
BusinessI.aegis.xml(若不用泛型,则必须添加此xml和BusinessI.java放在一个包下)
1. <?xml version="1.0" encoding="UTF-8"?>
2. <mappings>
3. <mapping>
4. <method name="getBooksByNames">
5. <parameter index="0" componentType="java.lang.String" />
6. <return-type componentType="stoneyang.bean.Book" />
7. </method>
8. <method name="getBooksWithSpecialYear">
9. <parameter index="0" componentType="stoneyang.bean.Book" />
10. <return-type componentType="stoneyang.bean.Book" />
11. </method>
12. </mapping>
13. </mappings>
<?xml version="1.0" encoding="UTF-8"?><mappings> <mapping> <method name="getBooksByNames"> <parameter index="0" componentType="java.lang.String" /> <return-type componentType="stoneyang.bean.Book" /> </method> <method name="getBooksWithSpecialYear"> <parameter index="0" componentType="stoneyang.bean.Book" /> <return-type componentType="stoneyang.bean.Book" /> </method> </mapping> </mappings>
================================================================================
BusinessImpl.java 提供给webservice的接口的实现
1. package stoneyang.businessIpml;
2.
3. import java.util.ArrayList;
4.
5. import java.util.List;
6.
7. import stoneyang.bean.Book;
8.
9. import stoneyang.businessI.BusinessI;
10.
11. public class BusinessImpl implements BusinessI{
12.
13.
14.
15. //通过书名得到一本书来模拟数据库操作
16.
17. public Book getBookByName(String name) {
18.
19. return new Book(name);
20.
21. }
22.
23. //根据已知的书名数组,得到书实例的集合来模拟数据库操作
24.
25. public List<Book> getBooksByNames(String[] bookNames) {
26.
27. List<Book> books = new ArrayList<Book>();
28.
29. for( String bookName : bookNames ){
30.
31. books.add(new Book( bookName ));
32.
33. }
34.
35. return books;
36.
37. }
38.
39. //得到同年出版的其他书籍来模拟数据库操作
40.
41. public List<Book> getBooksWithSpecialYear(Book book) {
42.
43. List<Book> books = new ArrayList<Book>();
44.
45. books.add(new Book(book.getName()+"翻印版",book.getYear()));
46.
47. books.add(new Book(book.getName()+"影音版",book.getYear()));
48.
49. return books;
50.
51. }
52.
53. }
package stoneyang.businessIpml; import java.util.ArrayList; import java.util.List; import stoneyang.bean.Book; import stoneyang.businessI.BusinessI; public class BusinessImpl implements BusinessI{ //通过书名得到一本书来模拟数据库操作 public Book getBookByName(String name) { return new Book(name); } //根据已知的书名数组,得到书实例的集合来模拟数据库操作 public List<Book> getBooksByNames(String[] bookNames) { List<Book> books = new ArrayList<Book>(); for( String bookName : bookNames ){ books.add(new Book( bookName )); } return books; } //得到同年出版的其他书籍来模拟数据库操作 public List<Book> getBooksWithSpecialYear(Book book) { List<Book> books = new ArrayList<Book>(); books.add(new Book(book.getName()+"翻印版",book.getYear())); books.add(new Book(book.getName()+"影音版",book.getYear())); return books; } }
Test.java 是远程调用的客户端,这里
(1) 通过远程调用得到一个book的实例,并在本地设置实例的年份;
(2) 通过远程调用,传入书名的数组,返回书实例的集合;(和(1)没有关系)
(3) 设置(1)的book实例再次进行远程调用得到同年份的book的集合;
1. package stoneyang.test;
2.
3. import java.net.MalformedURLException;
4.
5. import java.util.List;
6.
7. import org.codehaus.xfire.XFireFactory;
8.
9. import org.codehaus.xfire.client.XFireProxyFactory;
10.
11. import org.codehaus.xfire.service.Service;
12.
13. import org.codehaus.xfire.service.binding.ObjectServiceFactory;
14.
15.
16.
17. import stoneyang.bean.Book;
18.
19. import stoneyang.businessI.BusinessI;
20.
21. public class Test {
22.
23. public static void main(String args[]){
24.
25. //通过接口类创建Service对象
26.
27. Service srvcModel = new ObjectServiceFactory().create(BusinessI.class);
28.
29. //通过XFire的工厂类创建工厂对象
30.
31. XFireProxyFactory factory = new XFireProxyFactory(XFireFactory.newInstance().getXFire());
32.
33. //访问的地址
34.
35. String url="http://localhost:38088/xfireDemo/services/business";
36.
37. //异常处理
38.
39. try{
40.
41. //创建服务对象
42.
43. BusinessI srvc = (BusinessI) factory.create(srvcModel, url);
44.
45. //调用服务中的方法,并显示其结果
46.
47. Book book = srvc.getBookByName("《小红帽》");
48.
49. book.setYear("1986年");
50.
51. List<Book> books1 = srvc.getBooksByNames(new String[]{"《社会心理学》","《心理学与生活》"});
52.
53. List<Book> books2 = srvc.getBooksWithSpecialYear(book);
54.
55.
56.
57. System.out.println(book);
58.
59. for( Book b: books1 ){
60.
61. System.out.println( b );
62.
63. }
64.
65. for( Book b: books2 ){
66.
67. System.out.println( b );
68.
69. }
70.
71. } catch (MalformedURLException e) {
72.
73. e.printStackTrace();
74.
75. }
76.
77. }
78.
79. }
package stoneyang.test;import java.net.MalformedURLException; 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 stoneyang.bean.Book; import stoneyang.businessI.BusinessI; public class Test { public static void main(String args[]){ //通过接口类创建Service对象 Service srvcModel = new ObjectServiceFactory().create(BusinessI.class); //通过XFire的工厂类创建工厂对象 XFireProxyFactory factory = new XFireProxyFactory(XFireFactory.newInstance().getXFire()); //访问的地址 String url="http://localhost:38088/xfireDemo/services/business"; //异常处理 try{ //创建服务对象 BusinessI srvc = (BusinessI) factory.create(srvcModel, url); //调用服务中的方法,并显示其结果 Book book = srvc.getBookByName("《小红帽》"); book.setYear("1986年"); List<Book> books1 = srvc.getBooksByNames(new String[]{"《社会心理学》","《心理学与生活》"}); List<Book> books2 = srvc.getBooksWithSpecialYear(book); System.out.println(book); for( Book b: books1 ){ System.out.println( b ); } for( Book b: books2 ){ System.out.println( b ); } } catch (MalformedURLException e) { e.printStackTrace(); } } }
services.xml 是给Tomcat部署使用的,暴露接口做为webservice的服务
services.xml:
1. <?xmlversion="1.0"encoding="UTF-8"?>
2.
3. <beansxmlns="http://xfire.codehaus.org/config/1.0">
4.
5. <service>
6.
7. <name>business</name>
8.
9. <serviceClass>stoneyang.businessI.BusinessI</serviceClass>
10.
11. <implementationClass>stoneyang.businessIpml.BusinessImpl</implementationClass>
12.
13. <use>literal</use>
14.
15. <scope>application</scope>
16.
17. </service>
18.
19. </beans>
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://xfire.codehaus.org/config/1.0"> <service> <name>business</name> <serviceClass>stoneyang.businessI.BusinessI</serviceClass> <implementationClass>stoneyang.businessIpml.BusinessImpl</implementationClass> <use>literal</use> <scope>application</scope> </service> </beans>
二. 配置Tomcat
1、在Tomcat下新建应用为 xfireDemo,如图2,创建目录后,添加相关的文件:
WEB-INF:创建web.xml
1. <?xml version="1.0" encoding="ISO-8859-1"?>
2.
3. <!-- START SNIPPET: webxml -->
4.
5. <!DOCTYPE web-app
6.
7. PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
8.
9. "http://java.sun.com/dtd/web-app_2_3.dtd">
10.
11.
12.
13. <web-app>
14.
15.
16.
17. <servlet>
18.
19. <servlet-name>XFireServlet</servlet-name>
20.
21. <display-name>XFire Servlet</display-name>
22.
23. <servlet-class>
24.
25. org.codehaus.xfire.transport.http.XFireConfigurableServlet
26.
27. </servlet-class>
28.
29. </servlet>
30.
31.
32.
33. <servlet-mapping>
34.
35. <servlet-name>XFireServlet</servlet-name>
36.
37. <url-pattern>/servlet/XFireServlet/*</url-pattern>
38.
39. </servlet-mapping>
40.
41.
42.
43. <servlet-mapping>
44.
45. <servlet-name>XFireServlet</servlet-name>
46.
47. <url-pattern>/services/*</url-pattern>
48.
49. </servlet-mapping>
50.
51. </web-app>
52.
53. <!-- END SNIPPET: webxml -->
<?xml version="1.0" encoding="ISO-8859-1"?><!-- START SNIPPET: webxml --> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <servlet> <servlet-name>XFireServlet</servlet-name> <display-name>XFire Servlet</display-name> <servlet-class> org.codehaus.xfire.transport.http.XFireConfigurableServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>XFireServlet</servlet-name> <url-pattern>/servlet/XFireServlet/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>XFireServlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping> </web-app> <!-- END SNIPPET: webxml -->
WEB-INF/ classes:将IDE编译后输出目录下的所有文件夹拷贝到此处;
WEB-INF/lib:将之前配置IDE的所有jar包宝贝到此处;
部署后的文件目录:
三. 验证部署是否成功
开启Tomcat后,输入网址http://localhost:38088/xfireDemo/services/business?wsdl 后,若看到类似xml格式的内容,如下图,则部署成功;
四.远程调用
运行 stoneyang.test.Test.java 后得到结果:
名称: 《小红帽》 年份: 1986年
名称: 《社会心理学》
名称: 《心理学与生活》
名称: 《小红帽》翻印版 年份: 1986年
名称: 《小红帽》影音版 年份: 1986年