1. XFire介绍
XFire和Axis都是新一代的java web服务框架。XFire提供了非常方便的API,使用这些API可以开发面向服务(SOA)的程序。他比axis性能要高,支持各种标准,性能优良,基于低内存的STAX模型,也是其于流的XML。
? 支持多个重要的Web Service标准,包括SOAP、WSDL、WS-I Basic Profile、 WSAddressing、WS-Security等
? 高性能的SOAP栈
? 可选的绑定(binding)方式,如POJO、XMLBeansJAXB1.1、JAXB2.0、CastorJiBX等
? 支持JSR181 API
? 多种传输方式,如HTTP、JMS、XMPP、In-JVM等
? 灵活的接口
? 支持多个容器,如Spring、Pico
关于XFire就知道这么多,关于它的更祥细的资料或更深层次东西,就不去研究了,当然关于webservice的基本的知识还要学习的。作为技术人员不能光知其然,不知其所以然。(行了,又废话了)。
2. 准备
在开始介绍开发实例之前,你首先要准备工具有:eclipse、Myeclipse、weblogic8,当然你也可以自己下载最新xfire。http://repository.codehaus.org/org/codehaus/xfire/xfire-distribution/1.2.6/xfire-distribution-1.2.6.zip都准备好了 ,那就正式开工吧!
3. 开发
l? 服务端
首先,eclipse新建一个webservice工程
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
工程名字就叫JuneService,web root、content root都为June
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
一路next后,点击”Finish”,会看到如下结构,有了工具就是好,什么东西都自己生成,那先看看WEB-INF/web.xml都生成了什么吧。。
?
?
?
?
?
?
?
?
?
?
?
?
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
??? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4"
??? 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>
??????? <load-on-startup>0</load-on-startup>
??? </servlet>
??? <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.xml文件中定义了一个 XfireServlet,它负责提供Web Services,并提供
每个Web Service的WSDL。如果你发布了一个Web Service,比如叫JuneService,你
就可以通过网址http://<server_url[:port]>/<context>/ services/JuneService来访问这个Web Service,并且通过网址http://<server_url[:port]>/<context>/
services/BookService?WSDL得到这个Web Service的WSDL信息。
在源文件夹WEB-INF/src下新建一个java package:com.june,在这个package下新建一个接口JuneService,(往往很多文章在介绍某项技术怎么用时,都会用helloworld这个例子,这个例子确实应用广泛,不过,咱换一种例子,或都另一种方式的HelloWorld)
这个接口定义了只定义了一个addDate方法。这个方法要求传入一个整数的参数,返回类型为一个字符串,用来得到当的时间的加上n天以后的日期,也很简单吧。。
package com.june;
?
public interface JuneService {
??? public String addDate(int d);
}
最写一个实现这个接口的类
package com.june;
?
import java.util.Calendar;
?
public class JuneServiceImpl implements JuneService {
?
??? public String addDate(int d) {
??????? Calendar cal = Calendar.getInstance();
??????? cal.add(Calendar.DATE, d);
??????? SimpleDateFormat dateFormat = new SimpleDateFormat();
??????? dateFormat.applyPattern("yyyy年MM月dd日");
??????? return dateFormat.format(cal.getTime());
}
}
实现的很简单,就是加上天数后,直接tostring反回就可以了。
现在看来很简单吧,webserice的类跟普通的没有什么区别。好,继续吧。在WebServices目录下有一个services.xml文件,他就是用来发布你上面的这两个类做为webservice的,好,我们来配置一下这个文件。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xfire.codehaus.org/config/1.0">
??? <service>
??? ??? <name>HelloService</name>
??????? <namespace>http://services.june.come/JuneService</namespace>
??????? <serviceClass>
??????? ??? com.june.JuneService
??????? </serviceClass>
??????? <implementationClass>
??????????? com.june.JuneServiceImpl
??????? </implementationClass>
??? </service>
</beans>
好了,services.xml配置好了,关于services.xml配置结构这里也不说明了,大家可以去查资料,这里能说明问题就行了,那我就开始发布我们的webservice吧!说明一点,如果使用的不是eclipse工具,你可能要手动装services.xml文件考到WEB-INF/classes/META-INF/xfire下面。但是myeclipe都不用你关心这些事情,它替你搞定。
那就先发布到weblogic上,启动服务。在地址里输入http://localhost:7001/June/services
就可以看到我们的服务了,可是这是在其它web容器,但是在weblogic8上就不行,会出现如下的错误:org.springframework.beans.factory.BeanDefinitionStoreException: Error registering bean with name 'xfire.typeMappingRegistry' defined in class path resource [org/codehaus/xfire/spring/xfire.xml]: Class that bean class [org.codehaus.xfire.aegis.type.DefaultTypeMappingRegistry] depends on not found; nested exception is java.lang.NoClassDefFoundError: null
这个问题是怎么会事,难道是配置错了,可是查来查去没有什么错误呀。那到google上找(真不知道现在程序员如果没有Google会是什么样?),找了好长时间,终于在xfire的官网上找到相关的资料。如下:
XFire requires a newer version of the javax.xml.namespace.QName than is included in weblogic.jar. The QName jar can be found here
?
To override the weblogic.jar with your own QName.jar, your need to do the following:
?
Add the QName JAR file (qname.jar) into the WEB-INF/lib folder in your WAR file
Add a file weblogic.xml into the WEB-INF folder in your WAR file
Below is an example weblogic.xml file:
?
?
?
<!DOCTYPE weblogic-web-app PUBLIC
? "-//BEA Systems, Inc.//DTD Web Application 8.1//EN"
? "http://www.bea.com/servers/wls810/dtd/weblogic810-web-jar.dtd">
?
<weblogic-web-app>
? <container-descriptor>
??? <prefer-web-inf-classes>true</prefer-web-inf-classes>
? </container-descriptor>
</weblogic-web-app>
?
?
The purpose of the weblogic.xml file is to tell WebLogic that the the WEB-INF/lib folder should take precedence over the global weblogic.jar file. This allows you to override the system classloader with your own application-specific JAR files.
?
The other solution is to put qname.jar at the beginning of WLS classpath in startweblogic batch file.
Qname.jar 下载地址:http://docs.codehaus.org/download/attachments/27836/qname.jar?version=1
原来发生错误原因,是因为weblogic.jar包的qname.jar太旧了,确切的说是 qname.class,好那就按照解决方法做,把qname.jar加到工程中,在weblogic server也加上qname.jar,还要在startweblogic.cmd的classpath里加放%WL_HOME%/server/lib/qname.jar,或是直接替换weblogic.jar里的qname.class,这样启动时就会用这个新包了。加入weblogic.xml就是要用户自己的jar先于系统的jar加载。好了,再重启一下服务。
再输入地址http://localhost:7001/June/services,好,终于看我们期盼已久的界面了。这样我们webservice服务就发布成功了。
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
? ?l? 客户端
有了服务端,那我们就应用一下,下面我们来做webservice的客户端。
首先建一个java application工程。就叫JuneClient吧,这个工程很简单,什么也没有,那我先建一下src源目录,并做为建我们的java package com.june,client来做为webservice的客户端。在工程上右键new->others选择webservice client.
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
然后,next按照提示来设置。
Wsdl url填写刚发布成功的webservice的地址http://localhost:7001/June/services/JuneService?wsdl
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
这一步next,我这里的eclipse会报web 服务描述语言有错误,直接finish就OK了
这样,myeclipse就会自动生成客户端所需要的程序,有了工具确实是很方便,这样确实提高了开发效率,但是也造成了许多程序员没有工具就不会写程序,工具一通搞定,具体里面的关系也不用管,我觉得程序员不光要会用工具,还要知道工具怎么来实现的,为什么要设置这一步,在没有工具情况下,我应该先从那做起,明白原理后,再利于工具,才能对你有所提高。才能提高对整个系统的整体把握。不光要知其然,还要知其所然,这才是搞技术应有的态度。(哎,又废话了)
既然,自动生成了客户端程序,我们就来测试一下我们的webservice。
package com.june.client;
?
import com.june.client.JuneServiceClient;
import com.june.client.JuneServicePortType;
public class JuneClientMain {
?
??? public static void main(String[] args) {
??????? JuneServiceClient client = new JuneServiceClient();
??????? JuneServicePortType juneService = client.getJuneServiceHttpPort();
??????? // 调用服务
??????? String result = juneService.addDate(21);
??????? System.out.println(result);
??? }
}
以上为通过webservice客户端调用web服务的一个例子,我调用webservice的addDate()方法,参数传入21,然后运行这个程序。也就是说通过webservice应该返回当前日期加上21天那天的日期是多少,结果是:2008年08月08日。正好是北京奥运会的日子,好日子呀,哈哈。。
好了,其实webservice在好多地方都可以布署,也可以在web应用下,也可以桌面应用,C++、C#、VB等等。只要你提供相应的WSDL,告诉调用者相应的接口方法,只需传入相应的参数,就能得到你想要的结果。
?
?
?
关键点:
l? XFire、myeclipse、l? Weblogic8配置,qname.jar,startWebLogic.cmdl? Web服务描述语言l? Webservice客户端调用