16.3 将POJO Bean导出为Web Service
通过XFire为Spring提供的服务导出器可以轻松地将POJO导出为标准的Web Service,此外,XFire还允许我们使用JSR 181注解对POJO进行标注,无须使用XML配置就可以导出为Web Service,各种复杂的转换细节被巧妙地隐藏在XFire之中。
16.3.1 使用导出器导出Web Service
XFire为Spring提供了方便易用的导出器XFireExporter,借助XFireExporter的支持,我们可以在Spring容器中将一个POJO导出为Web Service。BbtForum是Baobaotao论坛业务服务类,它拥有众多的业务方法,我们现在希望将其提供查询最近几天精华帖子数的业务方法开放为Web Service。为了避免过多地开放不必要的接口方法,需要定义一个BbtForumService窄接口,它定义那些需要开放为Web Service的业务方法:
|
public
interface BbtForumService {
int getRefinedTopicCount(int lastDay);①
}
将一个业务类所有需要开放为Web Service的方法通过一个窄接口来描述是值得推荐的做法,这让Web Service的接口显得很“干净”。其次,XFire的导出器也需要服务接口的支持,因为它采用基于接口的动态代理技术。真实的业务类当然需要实现Web Service窄接口:
package com.baobaotao.service;
import javax.jws.WebService;
import com.baobaotao.xfire.server.BbtForumService;
public class BbtForum implements BbtForumService
public
int getRefinedTopicCount(int lastDay)
if(lastDay <= 2) return 10;
else if(lastDay <= 5) return 20;
else return 32;
}
…
}
BbtForum中的方法在真实的系统中应该引用其他的业务类或DAO获取数据库中的真实数据,为了简化实例,我们通过一段简单的代码进行模拟,如②所示。
在拥有了窄接口之后,剩余的工作就是在Spring配置文件中通过XFireExporter将BbtForum#getRefinedTopicCount()方法导出为Web Service,具体配置如代码清单 16‑1所示:
代码清单 16‑1 applicationContext.xml:将POJO导出Web Service

上面的配置将BbtForum所有定义在BbtForumService窄接口中的方法导出为Web Service。在XFire核心JAR包中拥有一个预定义的Spring配置文件,它定义了XFire在Spring中必须用到的一些Bean和资源,需要引入这个预定义的配置文件,如①所示。紧接着,就可以使用XFireExporter将业务类导出为Web Service了。②-1、②-2为导出器引入XFire环境,对于任何导出器,这都是标准的配置,所以如果有多个导出器,可以将这两个属性通过一个父<bean>标签进行抽象。而②-3、②-4分别定义了业务服务类及需要导出为Web Service方法的窄接口。Web Service的默认名称是窄接口的类名,即BbtForumService,用户可以通过name属性显式指定Web Service的名称,如②-5所示。
通过这个简单的配置,就完成了将业务服务类开放为Web Service的工作,接下来,我们就可以通过配置Web 服务器的web.xml,将其通过HTTP传输协议开放出去。
16.3.2 配置web.xml
一般情况下,我们通过HTTP作为Web Service的传输协议,这样用户只需要启动一个Web服务器(如Tomcat),客户端就可以通过HTTP访问到Web Service服务了。为了集成Spring容器,XFire专门提供了一个XFireSpringServlet,我们可以在web.xml中配置该Servlet,将Spring容器中定义的Web Service在某个URI下发布,如代码清单16-2所示:
代码清单16-2 web.xml 配置

首先,我们指定在代码清单16‑1中所配置的Spring配置文件,如①所示。然后定义一个XFireSpringServlet,让其截取所有/service URI下的请求,如②和③所示。
创建一个Tomcat配置文件baobaotao.xml,并编写一行映射配置(这里使用Tomcat 5.5),这种方式无须将Web应用打包成WAR,方便开发测试:
<Context path="/baobaotao" docBase="D:/masterSpring/chapter16/webapp"/>
将baobaotao.xml放置到<TOMCAT_HOME>/conf/Catalina/localhost目录下,启动Tomcat服务,键入http://localhost:8080/baobaotao/service/BbtForumService?wsdl,用户将可以看到BbtForumService对应的WSDL,如图16-3所示。

图16-3 BbtForumService的WSDL
阅读这个WSDL文档,我们可以知道BbtForum的getRefinedTopicCount已经被成功地发布为Web Service了。只要拿到这个WSDL就可以开发相应的客户端调用程序了。
16.3.3 使用JSR 181注解导出Web Service
前面两小节中,我们领教了XFireExporter导出器的威力。在需要导出为Web Service的业务类数目不大时,XFireExporter的配置方式非常优雅。但是,如果有很多需要导出为Web Service的业务类,用户必须分别为它们配置一个XFireExporter,这让我们回忆起了TransactionProxyFactoryBean(每一个需要事务功能的业务类需要分别配置)。在学习过@Transaction注解后,我们自然而然地希望使用类似注解技术完成Web Service导出的工作。
JSR 181就是为此目的而提出的,它是BEA领导的一个Web Service规范。XFire已经支持JSR 181 2.0,用户既可以使用JDK 5.0的注解,也可以在JDK 5.0之前的版本中使用commons-attributes注解。使用JSR 181的明显好处是,用户只需要在业务类和窄接口标注JSR 181注解,不管有多少需要导出为Web Service的业务类,只需要在Spring中配置一个XFire提供的JSR 181注解增强Bean就可以了。注解增强处理器会对Spring容器中所有标注JSR 181注解的业务类进行处理,并分别将它们导出为Web Service。使用JSR 181时,必须将XFire的依赖类库xfire-jsr181-api-1.0-M1.jar添加到类路径中。
如果输入、输出的对象类型仅包括基本类型的属性,只需要在业务类和窄接口中分别使用@WebService注解进行简单的配置就可以了,XFire将根据默认约定导出Web Service。
窄接口只需要定义一个@WebService注解,并指定SOAP的命名空间就可以了:

如果碰到以下应用场景:输入、输出对象是复杂的对象(如未使用泛型的集合类),当返回类型是一个对象但不希望输出所有的结果,或者不希望使用默认的属性名。这时可以在业务方法中通过@WebMethod、@WebResult等注解提供额外的信息来达到目的。更多关于JSR 181的信息请参考:http://dev2dev.bea.com/webservices/jwsm.html。
按照相似的方式,可以为应用中其他的业务类进行Web Service标注,在完成标注后,需要在Spring配置中启用XFire JSR 181处理器,对Spring容器中所有标注@WebService的Bean进行统一的处理,以便执行真正Web Service的导出工作。XFire在Spring中对应的配置如下所示:
代码清单16-3 applicationContext.xml:使用JSR 181导出Web Service

重启Tomcat,查看http://localhost:8080/baobaotao/service/BbtForumService?wsdl,用户依旧可以看到如图16-3所示的WSDL。






