使用XFire进行web services开发有三种方式:
1. 不集成Spring: 配置services.xml 文件和web.xml(配置org.codehaus.xfire.transport.http.XFireConfigurableServlet servlet)
2. Spring使用XFireSpringServlet方式。
3.Spring集成使用org.springframework.web.servlet.DispatcherServlet方式
使用XFireSpringServlet进行实现的步骤:
1、定义服务接口;
2、实现服务接口;
3、更新web.xml添加Spring监听器相关XFire相关的servlet(即添加XFireSpringServlet)和Spring监听器;
4、在Spring文件application.xml配置ServiceBean;
5、测试web services是否部署成功
参考searcher项目中applicationContext_webservice.xml中的配置
1、定义服务接口
package com.mybank.xfire.example;
public interface IBankingService {
public String transferFunds(
String fromAccount, String toAccount, double amount, String currency);
}
注:服务接口不能少,客户端访问web services就是通过接口进行访问的,实现类对客户端是透明的。
2、实现服务接口
package com.mybank.xfire.example;
import java.text.NumberFormat; i
import java.text.DecimalFormat;
public class BankingService implements IBankingService {
public BankingService(){
}
public String transferFunds(
String fromAccount, String toAccount, double amount, String currency){
String statusMessage = "";
try {
NumberFormat formatter = new DecimalFormat("###,###,###,###.00");
statusMessage = "COMPLETED: " + currency + " " + formatter.format(amount)+
" was successfully transferred from A/C# " + fromAccount + " to A/C# " + toAccount;
} catch (Exception e){
statusMessage = "BankingService.transferFunds(): EXCEPTION: " + e.toString();
}
return statusMessage;
}
}
注:BankingService的transferFunds返回类型是String,如果是复杂类型需要Aegis进行数据绑定。
3、配置web.xml
<web-app>
<display-name>Spring Image Database</display-name>
<description>Spring Image Database sample application</description>
<!--配置spring上下文文件路径-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml
</param-value>
</context-param>
<!--配置log4j日志监听器-->
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<!-- 配置spring上下文加载监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<!--配置处理XFire处理web服务请求的servlet-->
<servlet-name>XFireServlet</servlet-name>
<display-name>XFire Servlet</display-name>
<servlet-class>org.codehaus.xfire.spring.XFireSpringServlet</servlet-class>
</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>
注:使用Spring管理XFire bean就应该配置Spring监听器和spring上下文配置文件路径。
4、在Spring上下文配置文件application.xml中配置XFire ServiceBean
<beans>
<!--引入xfire.xml 这个文件包含了定义TransportManager,ServiceRegistry,和一些简单的ServiceFactorys的bean-->
<import resource="classpath:org/codehaus/xfire/spring/xfire.xml"/>
<bean name="BankService" class="org.codehaus.xfire.spring.ServiceBean">
<property name="serviceBean" ref="bank"/>
<property name="serviceClass" value="com.mybank.xfire.example.IBankingService"/>
<property name="inHandlers">
<list>
<ref bean="addressingHandler"/>
</list>
</property>
</bean>
<bean id="addressingHandler" class="org.codehaus.xfire.addressing.AddressingInHandler"/>
<bean id="bank" class="com.mybank.xfire.example.BankingService"/>
</beans>
5、客户端测试:
首先把服务器端的打成jar包
新建一个web动态工程,添加包,
创建一个测试类:
Xml代码
import java.net.MalformedURLException;
import java.rmi.RemoteException;
import org.codehaus.xfire.client.XFireProxyFactory;
import org.codehaus.xfire.service.Service;
import org.codehaus.xfire.client.*;
import org.codehaus.xfire.service.binding.ObjectServiceFactory;
import com.zx.xfiretext.domain.User;
import com.zx.xfiretext.webserver.UserService;
public class MyClient
{
public static void main(String[] args)
{
try {
Service serviceModel = new ObjectServiceFactory() .create(UserService.class);
UserService service = (UserService) new XFireProxyFactory().create( serviceModel, "http://localhost:8080/XFireService/services/UserService");
User user = service.queryUserByAccoutId("123");
System.out .println("userId=" + user.getUserId() + ", userName=" + user.getUserName() + ", lastLogin=" + user.getLastLogin());
}
catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
运行测试类,如果在控制台输入的是
userId=123, userName=测试用户, lastLogin=Thu May 22 11:26:48 CST 2008
则说明测试成功。
Ps:如果出现javax.xml.transform.TransformerFactoryConfigurationError: Provider org.apache.xalan.processor.TransformerFactoryImpl not found错误,
错误原因是:
认为是由于jdk1.5 与 tomcat5.0之间的关于 TransformerFactoryImpl 类的冲突造成的。
tomcat-5.0.28\common\endorsed下有两个jar包:xercesImpl.jar和xml-apis.jar,其中的类 javax.xml.transform.TransformerFactory 与jdk1.5中的类org.apache.xalan.processor.TransformerFactoryImpl其实是同一个类。
in tomcat java is called with the following argument:
-Djava.endorsed.dirs="X:\my_app\Portal\tomcat\common\endorsed"
In this directory you find two jar files: xercesImpl.jar and xml-apis.jar needed by tomcat and that must be loaded before all xmsl stuff present in the jdk (1.4 naming problem). And in the file xml-apis.jar the TransformerFactoryImpl is set to "org.apache.xalan.processor.TransformerFactoryImpl".
解决办法:
1. 将xml-apis.jar移出endorsed文件夹。
2. 用xalan系列jar包替换原来的xercesImpl.jar和xml-apis.jar。
xalan系列jar包:serializer.jar、xalan.jar、xercesImpl.jar和xml-apis.jar。