Struts2 + spring2.5 + ibatis 框架整合已成功。(前面已经说明)
XFire
是与Axis 2并列的新一代Web Service框架,通过提供简单的API支持Web Service各项标准协议,帮助你方便快速地开发Web Service应用。
相对于Axis来说,目前XFire相对受欢迎,加上其提供了和Spring集成的支持,在目前的Web Service开源社区拥有众多的追随者。并且因为XFire为Spring提供的支持,使得我们可以很容易在Spring中使用XFire构建Web Service应用。
XFire与Axis2相比具有如下特征:
l 支持一系列Web Service的新标准--JSR181、WSDL2.0 、JAXB2、WS-Security等;
l 使用Stax解释XML,性能有了质的提高。XFire采用Woodstox 作Stax实现;
l 容易上手,可以方便快速地从pojo发布服务;
l 支持Spring、Pico、Plexus、Loom等容器;
l 灵活的Binding机制,包括默认的Aegis,xmlbeans,jaxb2,castor;
l 高性能的SOAP 栈设计;
l 支持Spring、Pico、Plexus、Loom等容器。
XFire与Axis1性能的比较如下:
l XFire比Axis1.3快2-6倍;
l XFire的响应时间是Axis1.3的1/2到1/5。
XFire在WebService框架中开始较晚,它从现有的框架中借鉴了许多优秀的理念,力争将Web Service的应用开发难度降到最低。此外,还提供了各种绑定技术、支持多种传输协议,对WebService体系中许多新的规范提供了支持。
下面让我们来看一个XFire于Spring集成的helloWorld的简单例子。
一.实现的功能和特点
本例具有如下功能和特点:
1) 基于J2EE平台的Web Service服务;
2) 开发方便,配置简单;
3) 与spring无缝集成。
XFire是完全基于流数据处理进行工作的系统,这意味着XFire不是将整个SOAP文档缓存在内存中,而是以管道的方式接收SOAP流数据。这种工作方式的转变带来了可观的性能回报,同时节省了内存的占用。
XFire从管道中接收一个SOAP请求到返回一个SOAP响应,会经历一系列的阶段。在管道调用的任何一个阶段,XFire都可以添加一些额外的Handler,在对消息进行加工处理后再传入到下一个阶段中。在SOAP请求消息对Web Service发起真正调用之前,分别会经过传输、预转发、转发、策略实施、用户信息处理、预调用、服务调用等阶段。
二.开发环境
笔者的开发环境描述如下:
1) jdk: 1.6版本;
2) Tomcat:6.0;
3) MyEclipse:8.5。
三.开发步骤
1. 工程与环境的建立
在MyEclipse中新建Web工程,名为Unite2.0。SSI2的框架已经整合完毕。为了不出现冲突。手动导入xfire包。(之前用MyEclipse自带的导入总是无缘无故的报一些奇怪的错误)。
首先导包
WEB-INF/lib的jar包需要导入jar列表:
activation- 1.1.jar,commons-beanutils-1.7.0.jar,commons-codec-1.3.jar,commons- logging-1.0.4.jar,jaxen-1.1-beta-9.jar,jaxws-api-2.0.jar,jdom- 1.0.jar,jsr173_api-1.0.jar,mail-1.4.jar,saaj-api-1.3.jar,saaj-impl- 1.3.jar,stax-api-1.0.1.jar,wsdl4j-1.6.1.jar,wstx-asl-3.2.0.jar,xbean- 2.2.0.jar,xbean-spring-2.8.jar,xfire-aegis-1.2.6.jar,xfire-annotations- 1.2.6.jar,xfire-core-1.2.6.jar,xfire-java5-1.2.6.jar,xfire-jaxws- 1.2.6.jar,xfire-jsr181-api-1.0-M1.jar,xfire-spring-1.2.6.jar,XmlSchema- 1.1.jar。
为了后续的客户端的测试,还需读者加入commons-httpclient.jar包到WEB-INF/lib下。
2.Web Service实现的编写
Web Service服务端提供一个根据输入的名字信息回复相应的sayHello信息的。下面让我们一步一步来开始进行编码。
1)web.xml的配置
一般情况下,我们通过HTTP作为Web Service的传输协议,这样我们只需启动一个Web服务器(如Tomcat,在本例中使用的是Tomcat6.0),这样客户端就可以通过HTTP访问到Web Service服务。为了集成Spring容器,XFire专门提供一个XFireSpringServlet,我们可以在web.xml中配置该Servlet,将Spring容器中定义的Web Service在某个URI下发布。
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
<!-- begin Spring Sturts配置 -->
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/applicationContext.xml</param-value>
</context-param>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- end Spring Sturts配置 -->
<!-- begin XFire 配置 -->
<servlet>
<!-- 配合Spring容器中XFire一起工作的Servlet-->
<servlet-name>XFireServlet</servlet-name>
<servlet-class>org.codehaus.xfire.spring.XFireSpringServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>XFireServlet</servlet-name>
<!-- 在这个URI下开放Web Service服务 -->
<url-pattern>/service
public interface IHelloService {
public String sayHello(String ttt);
public Course choose(User u);
public List<Course> getList(List<String> paramList);
}
HelloServiceImpl.java:
package demo;
import java.util.ArrayList;
import java.util.List;
public class HelloServiceImpl implements IHelloService {
public String sayHello(String ttt) {
return "Hello, " + ttt;
}
public Course choose(User user) {
System.out.println(user.getName());
Course course = new Course();
course.setName("choose: Eee");
List<User> userList = new ArrayList<User>();
userList.add(user);
course.setUserList(userList);
return course;
}
public List<Course> getList(List<String> paramList) {
for (int i = 0; i < paramList.size(); i++) {
System.out.println((String) paramList.get(i));
}
List<Course> courseList = new ArrayList<Course>();
Course course = new Course();
course.setName("getList: EeeDDDDDD");
User user = new User();
user.setName("getList: liaokun");
List<User> userList = new ArrayList<User>();
userList.add(user);
course.setUserList(userList);
courseList.add(course);
return courseList;
}
}
User.java:
package demo;
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Course.java:
package demo;
import java.util.List;
public class Course {
private String name;
private List<User> userList;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<User> getUserList() {
return userList;
}
public void setUserList(List<User> userList) {
this.userList = userList;
}
}
3)Spring配置文件applicationContext.xml的配置
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<context:annotation-config></context:annotation-config>
<bean id="dataSource"
class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="${jdbc.driverClass}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />
<property name="minPoolSize" value="${jdbc.minPoolSize}" />
<property name="maxPoolSize" value="${jdbc.maxPoolSize}" />
<property name="maxIdleTime" value="${jdbc.maxIdleTime}" />
<property name="acquireIncrement"
value="${jdbc.acquireIncrement}" />
<property name="maxStatements" value="${jdbc.maxStatements}" />
<property name="initialPoolSize"
value="${jdbc.initialPoolSize}" />
<property name="idleConnectionTestPeriod"
value="${jdbc.idleConnectionTestPeriod}" />
<property name="acquireRetryAttempts"
value="${jdbc.acquireRetryAttempts}" />
</bean>
<bean id="sqlMapClient"
class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation">
<value>/WEB-INF/iBatis/SqlMapConfig.xml</value>
</property>
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
<bean id="propertyConfig"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>/WEB-INF/iBatis/jdbc.properties</value>
</property>
</bean>
<bean id = "user_Service" class="com.unite.service.User_service"></bean>
<bean id= "user_dao" class="com.unite.dao.User_dao">
<property name="sqlMapClient">
<ref bean="sqlMapClient"/>
</property>
</bean>
<!--以上就不多说了,上篇文章提到了,用的是一个列子-->
<!--引入XFire的预配置文件-->
<import resource="classpath:org/codehaus/xfire/spring/xfire.xml" />
<bean id="HelloServiceImpl" class="demo.HelloServiceImpl" />
<!-- 使用导出器导出Web Service -->
<bean id="HelloService"
class="org.codehaus.xfire.spring.remoting.XFireExporter" ><!-- XFire导出器 -->
<!-- 引用XFire.xml中定义工作 -->
<property name="serviceFactory" ref="xfire.serviceFactory" />
<!-- 引用XFire.xml中定义的XFire实例 -->
<property name="xfire" ref="xfire" />
<!-- 业务服务Bean -->
<property name="serviceBean" ref="HelloServiceImpl" />
<!-- 业务服务Bean的窄接口类 -->
<property name="serviceClass"
value="demo.IHelloService" />
<!-- Web Service名称 -->
<property name="name" value="HelloServiceUT"/>
</bean>
</beans>
到此整个配置就完成了。
打开浏览器输入http://localhost:8080/Unite2.0/service/HelloServiceUT?wsdl
看是否打印出wsdl文件的信息。打印出了就是正常,未打印说明出问题了。
好,下面写个测试类ServiceTest.java 进行测试下。
package demo;
import java.util.ArrayList;
import java.util.List;
import org.codehaus.xfire.client.XFireProxyFactory;
import org.codehaus.xfire.service.Service;
import org.codehaus.xfire.service.binding.ObjectServiceFactory;
public class ServiceTest {
public void invokeService() throws Exception{
//根据窄接口创建Service模型
Service serviceModel = new ObjectServiceFactory()
.create(IHelloService.class);
//服务对应的URL地址
String serviceURL = "http://localhost:8080/Unite2.0/service/HelloServiceUT";
IHelloService service = null;
try {
//创建一个Web Service的访问实例,并将其转换为窄接口类型。
service = (IHelloService) new XFireProxyFactory().create(
serviceModel, serviceURL);
} catch (Exception e) {
throw new RuntimeException(e);
}
//以下为调用各个Web Service方法
//Test sayHello
String str = service.sayHello("dreava");
System.out.println("sayHello(): " + str);
//Test getList
List<String> list = new ArrayList<String>();
for(int i = 0; i < 5; i ++){
list.add("this is: " + i);
}
List<Course> courseList = (List<Course>)service.getList(list);
System.out.println("getList(): ");
for (Course course : courseList) {
System.out.println(course.getName());}
//Test choose
User user = new User();
user.setName("dreava");
Course course = service.choose(user);
System.out.println("choose(): ");
System.out.println(course.getName());
}
public static void main(String[] args) throws Exception{
ServiceTest client = new ServiceTest();
client.invokeService();
}
}
运行main 发现打印出:
log4j:WARN No appenders could be found for logger (org.codehaus.xfire.transport.DefaultTransportManager).
log4j:WARN Please initialize the log4j system properly.
sayHello(): Hello, dreava
getList():
getList: EeeDDDDDD
choose():
choose: Eee
整个过程完成。