随着SOA的广泛普及,很多人开始学习一些基于soap的webService技术,xfire正是其中非常优秀的代表。虽然xfire已经停止更新,并被并入cxf项目中,但是它的简单易用,能够使开发速度和学习成本大大降低,并且可以和Spring完美结合。所以就目前来说xfire仍然是小型WebService项目的一个非常好的选择。
下面我们就针对xfire在eclipse中的使用来进行讲解,希望能够起到抛砖引玉的作用。
此外,本文章借鉴了很多大侠的博文,并增加了一些我在使用过程中碰到的问题,所以属于共同智慧的结果,希望大家积极参与共享知识的工作中。
WebService:
1、建立一个 “Web Project”,名称为Server,其他都用默认,“finish“即可。
2、
将
xfire-distribution-1.2.6.zip
解压缩后,把
xfire-all-1.2.6.jar
和
lib
目录下的所有
jar
包都拷贝到项目的
WebContent/WEB-INF/lib
目录下。
3、编写一个用于发布的类文件HelloService.java
package
demo;
public class HelloService {
public String sayHello(String name) {
return name + " ,你好! " ;
}
}
public class HelloService {
public String sayHello(String name) {
return name + " ,你好! " ;
}
}
4、配置XML文件,这也是非常重要的、容易出错的地方。
先说
services.xml
,它是对所有要发布的服务的描述文件,
xfire
就是依据这些信息来发布你的服务。这里针对我们刚才那个类建立
services.xml
。内容如下:
<?
xml version="1.0" encoding="UTF-8"
?>
< beans xmlns ="http://xfire.codehaus.org/config/1.0" >
< service >
< name > HelloService </ name >
< serviceClass > demo.HelloService </ serviceClass >
</ service >
</ beans >
< beans xmlns ="http://xfire.codehaus.org/config/1.0" >
< service >
< name > HelloService </ name >
< serviceClass > demo.HelloService </ serviceClass >
</ service >
</ beans >
service 标签的子标签不止这两个,但其余的都是可选的。关于 services 的更多描述,请参阅 xfire 的官方网站。文件建好了,就是把它放到项目的哪个位置的问题了,这里我在项目的 WebContent/ META-INF 目录下面新建一个 xfire 文件夹,把 services.xml 文件放到这个新建文件夹里。最后再把 META-INF 文件夹整个移到 WebContent/ WEB-INF 目录下,这时 services.xml 文件的配置全部完成,如果我说的还不清楚,请直接看图一,图中左侧有文件结构,只要照那个结构调整项目中的文件及文件夹的位置就可以了。

注意,如果services.xml文件的放置位置不对,在用http://localhost:8081/
Server/services/网址访问服务器时,会抛出下面的异常:
Exception:
javax.servlet.ServletException: Error initializing XFireServlet.
root cause:
org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [META-INF/xfire/services.xml]; nested exception is java.io.FileNotFoundException: class path resource [META-INF/xfire/services.xml] cannot be opened because it does not exist
然后是web.xml文件,在项目已有的web.xml文件基础上修改一下就可以。修改后的最终内容如下:
<?
xml version="1.0" encoding="UTF-8"
?>
< web-app version ="2.4"
xmlns ="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation ="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" >
< 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 > /servlet/XFireServlet/* </ url-pattern >
</ servlet-mapping >
< servlet-mapping >
< servlet-name > XFireServlet </ servlet-name >
< url-pattern > /services/* </ url-pattern >
</ servlet-mapping >
< welcome-file-list >
< welcome-file > index.jsp </ welcome-file >
</ welcome-file-list >
</ web-app >
< web-app version ="2.4"
xmlns ="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation ="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" >
< 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 > /servlet/XFireServlet/* </ url-pattern >
</ servlet-mapping >
< servlet-mapping >
< servlet-name > XFireServlet </ servlet-name >
< url-pattern > /services/* </ url-pattern >
</ servlet-mapping >
< welcome-file-list >
< welcome-file > index.jsp </ welcome-file >
</ welcome-file-list >
</ web-app >
注意,以上8081是我设定的tomcat端口,这个没关系,可以改成你自己使用的tomcat端口

这里我保留<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
因为有的时候WebService和Web Project是在一起用的,是否保留可以自行决定。
到这里第一部分的所有步骤已经完成,打开
Tomcat
,在服务器上运行这个动态
web
项目。输入网址
http://localhost:8081/Server/services/HelloService?wsdl
,如果正确发布,会得到如图一中显示的
wsdl
文档。

以后要访问这个web服务的wsdl文件,只需要把Tomcat打开,然后输入上面的网址就可以了,这在第二部分创建客户端访问web服务时要用到。好了,web服务的发布就完成了。
这里还有一个提示,有一次我是用这样的方法建立xfire WebServices的时候,却不能够编译通过。现象和上面由于services.xml位置错误产生的错误的结果比较相似,可是经过研究发现,由于之前我使用了cxf项目,在我的tomcat/share/lib路径下放置了一些cxf、spring、ant等等jar包。正是由于这些和我项目中加载的jar产生了冲突导致了这样的结果。
这只是其中一种错误,在实际开发中是千奇百怪的错误,所以建议大家遇到困难冷静的分析可能产生问题的方方面面,别太迷信别人的说法,真正的问题只有自己能发现。
好不说题外话了,下面介绍Client的做法。
Client:
利用eclipse开发client的方法有很多种,这里我们介绍我认为最简单的一种,我们只需要写很少的代码就可以访问WebService中的方法。
1、安装eclipse插件。
打开Eclipse的Help菜单,选择”Software Updates”,然后再选择”Find and Install.”
选择"Search for new features to install",然后点击Next
选择"Create New Remote Site", 在name中输入"XFire",在eclipse update site中输入http://dist.codehaus.org/xfire/update/
选择OK
选择Finish。
选择"Search for new features to install",然后点击Next
选择"Create New Remote Site", 在name中输入"XFire",在eclipse update site中输入http://dist.codehaus.org/xfire/update/
选择OK
选择Finish。
2、新建一个java project。命名为“Client”,其他默认,finish。
3、File->New->Other ,选择“XFire”文件夹下的“Code generation from WSDL document”,打开代码生成向导,如图所示。

WSDL的地址栏填入http://localhost:8080/WSProject/services/HelloService?wsdl,Output directory栏中点浏览按钮,选择我们刚才新建的项目XFireProject,这两项是必填的。可选项中,package一栏可以选已经存在的包名,如果不填这一项,代码生成器会在wsdl目标命名空间的基础上创建一个。
完成后,可以看到项目中多了XFire类库,还有package下面的生成的一些类。此时要保证IDE的Tomcat服务器是打开的。
此时,在调用服务之前,还有一个重要的步骤,从XFireProject项目的右键菜单里调出Properties配置窗口,选中左面一栏中的XFire项,右面会列出所有与XFire运行有关的类库,按图中所示的,选中一些类库,这些类库在调用本服务时是必须的。
此时,在调用服务之前,还有一个重要的步骤,从XFireProject项目的右键菜单里调出Properties配置窗口,选中左面一栏中的XFire项,右面会列出所有与XFire运行有关的类库,按图中所示的,选中一些类库,这些类库在调用本服务时是必须的。

所有的配置都已经完成,最后就是编写代码完成调用。代码如下:
package
myClient;
import demo.HelloServiceClient;
import demo.HelloServicePortType;
public class Invoke {
/**
* 这个方法调用web服务并返回服务执行的结果
* @param yourName
* @return
*/
public static String invokeServiceNow(String yourName)
{
HelloServiceClient service = new HelloServiceClient();
HelloServicePortType port = service.getHelloServiceHttpPort();
return port.sayHello(yourName);
}
/** *//**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String MyName = " xfire " ;
System.out.println(Invoke.invokeServiceNow(MyName));
}
}
import demo.HelloServiceClient;
import demo.HelloServicePortType;
public class Invoke {
/**
* 这个方法调用web服务并返回服务执行的结果
* @param yourName
* @return
*/
public static String invokeServiceNow(String yourName)
{
HelloServiceClient service = new HelloServiceClient();
HelloServicePortType port = service.getHelloServiceHttpPort();
return port.sayHello(yourName);
}
/** *//**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String MyName = " xfire " ;
System.out.println(Invoke.invokeServiceNow(MyName));
}
}
最后程序运行得到的输出结果是“xfire,你好!”。
注意:在运行调用程序时,Tomcat也必须是打开的。