选框架犹如选媳妇,选来选去,最后我还是选了“丑媳妇(CXF)”,为什么是它?因为 CXF 是 Apache 旗下的一款非常优秀的 WS 开源框架,具备轻量级的特性,而且能无缝整合到 Spring 中。
其实 CXF 是两个开源框架的整合,它们分别是:Celtix 与 XFire,前者是一款 ESB 框架,后者是一款 WS 框架。话说早在 2007 年 5 月,当 XFire 发展到了它的鼎盛时期(最终版本是 1.2.6),突然对业界宣布了一个令人震惊的消息:“XFire is now CXF”,随后 CXF 2.0 诞生了,直到 2014 年 5 月,CXF 3.0 降临了。真是 7 年磨一剑啊!CXF 终于长大了,相信在不久的将来,一定会取代 Java 界 WS 龙头老大 Axis 的江湖地位,貌似 Axis 自从 2012 年 4 月以后就没有升级了,这是要告别 Java 界的节奏吗?还是后面有更大的动作?
如何使用 CXF 开发基于 SOAP 的 WS 呢?
这就是我今天要与您分享的内容,重点是在 Web 容器中发布与调用 WS,这样也更加贴近我们实际工作的场景。
在 CXF 这个主角正是登台之前,我想先请出今天的配角 Oracle JAX-WS RI,简称:RI(日),全称:Reference Implementation,它是 Java 官方提供的 JAX-WS 规范的具体实现。
先让 RI 来跑跑龙套,先来看看如何使用 RI 发布 WS 吧!
1. 使用 RI 发布 WS
第一步:整合 Tomcat 与 RI
这一步稍微有一点点繁琐,不过也很容易做到。首先您需要通过以下地址,下载一份 RI 的程序包:
https://jax-ws.java.net/2.2.8/
下载完毕后,只需解压即可,假设解压到 D:/Tool/jaxws-ri 目录下。随后需要对 Tomcat 的config/catalina.properties
文件进行配置:
common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar,D:/Tool/jaxws-ri/lib/*.jar
注意:以上配置中的最后一部分,其实就是在 Tomcat 中添加一系列关于 RI 的 jar 包。
看起来并不复杂哦,只是对现有的 Tomcat 有所改造而已,当然,您将这些 jar 包全部放入自己应用的 WEB-INF/lib 目录中也是可行的。
第二步:编写 WS 接口及其实现
接口部分:
<!-- lang: java -->
package demo.ws.soap_jaxws;
import javax.jws.WebService;
@WebService
public interface HelloService {
String say(String name);
}
实现部分:
<!-- lang: java -->
package demo.ws.soap_jaxws;
import javax.jws.WebService;
@WebService(
serviceName = "HelloService",
portName = "HelloServicePort",
endpointInterface = "demo.ws.soap_jaxws.HelloService"
)
public class HelloServiceImpl implements HelloService {
public String say(String name) {
return "hello " + name;
}
}
注意:接口与实现类上都标注 javax.jws.WebService
注解,可在实现类的注解中添加一些关于 WS 的相关信息,例如:serviceName
、portName
等,当然这是可选的,为了让生成的 WSDL 的可读性更加强而已。
第三步:在 WEB-INF 下添加 sun-jaxws.xml 文件
就是在这个 sun-jaxws.xml 文件里配置需要发布的 WS,其内容如下:
<!-- lang: xml -->
<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0">
<endpoint name="HelloService"
implementation="demo.ws.soap_jaxws.HelloServiceImpl"
url-pattern="/ws/soap/hello"/>
</endpoints>
这里仅发布一个 endpoint,并配置三个属性:WS 的名称、实现类、URL 模式。正是通过这个“URL 模式”来访问 WSDL 的,马上您就可以看到。
第四步:部署应用并启动 Tomcat
当 Tomcat 启动成功后,会在控制台上看到如下信息:
2014-7-2 13:39:31 com.sun.xml.ws.transport.http.servlet.WSServletDelegate <init>
信息: WSSERVLET14: JAX-WS servlet 正在初始化
2014-7-2 13:39:31 com.sun.xml.ws.transport.http.servlet.WSServletContextListener contextInitialized
信息: WSSERVLET12: JAX-WS 上下文监听程序正在初始化
哎呦,不错哦!还是中文的。
随后,立马打开您的浏览器,输入以下地址:
http://localhost:8080/ws/soap/hello
如果不出意外的话,您现在应该可以看到如下界面了:
看起来这应该是一个 WS 控制台,方便我们查看发布了哪些 WS,可以点击上面的 WSDL 链接可查看具体信息。
看起来 RI 确实挺好的!不仅仅有一个控制台,而且还能与 Tomcat 无缝整合。但 RI 似乎与 Spring 的整合能力并不是太强,也许是因为 Oracle 是 EJB 拥护者吧。
那么,CXF 也具备 RI 这样的特性吗?并且能够与 Spring 很好地集成吗?
CXF 不仅可以将 WS 发布在任何的 Web 容器中,而且还提供了一个便于测试的 Web 环境,实际上它内置了一个 Jetty。
我们先看看如何启动 Jetty 发布 WS,再来演示如何在 Spring 容器中整合 CXF。
2. 使用 CXF 内置的 Jetty 发布 WS
第一步:配置 Maven 依赖
如果您是一位 Maven 用户,那么下面这段配置相信一定不会陌生:
<!-- lang: xml -->
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>