Java 中包含的 JAX-WS 实现?

Posted

技术标签:

【中文标题】Java 中包含的 JAX-WS 实现?【英文标题】:JAX-WS Implementation included with Java? 【发布时间】:2013-03-25 18:26:38 【问题描述】:

我有一个 JAX-WS Web 服务应用程序,它部署为 Tomcat 7 的 WAR 文件。它使用了最新版本的 Metro 库,我将其包含在 WAR 文件中,并且运行良好。

我正在尝试简化部署包。我知道 Sun JDK 包含 Metro 的副本(例如,请参阅 this question 和 this one),但出于某种原因,显然必须用从 glassfish 站点下载的 Metro 副本替换此副本。我试图了解是否可以仅使用 Tomcat 和 JDK 附带的 Metro 实现,或者如果不能,为什么不这样做。

WAR的内容如下(类文件去掉):

META-INF/MANIFEST.MF
WEB-INF/classes/
WEB-INF/classes/com/[et cetera]
WEB-INF/ibm-web-ext.xml
WEB-INF/lib/
WEB-INF/lib/stax-api.jar
WEB-INF/lib/webservices-api.jar
WEB-INF/lib/webservices-extra-api.jar
WEB-INF/lib/webservices-extra.jar
WEB-INF/lib/webservices-rt.jar
WEB-INF/lib/webservices-tools.jar
WEB-INF/sun-jaxws.xml
WEB-INF/web.xml
wsdl/
wsdl/MyService.wsdl

web.xml 部分包含:

<servlet>
    <servlet-name>MyService</servlet-name>
    <servlet-class>
        com.sun.xml.ws.transport.http.servlet.WSServlet
    </servlet-class>              
</servlet>

当我从 WAR 中删除 webservices-* jars-- Metro jars--时,web 服务失败并出现错误“Wrapper cannot find servlet class com.sun.xml.ws.transport.http.servlet.WSServlet或它所依赖的类”。这并不奇怪,因为我在 Java 7 SE 附带的 jar 中的任何地方都找不到该类。

那么,如果您必须下载另一个 Metro 副本才能使类似的东西工作,那么说 Java 7 附带 Metro 意味着什么?是否可以仅使用 Java 附带的 jar 在 Tomcat 中运行 JAX-WS Web 服务?

【问题讨论】:

【参考方案1】:

这是一个老问题,但如果有人仍在寻找答案。从 JDK 1.7 开始,不需要包含 jaxws jar(我使用的是 1.7.0_45)。使用此http://www.mkyong.com/webservices/jax-ws/deploy-jax-ws-web-services-on-tomcat/ 链接构建示例 Web 服务并跳过第 5 步,一切正常。我的目标是 Tomcat 版本 7.0.47,整个项目是使用 Maven 构建的,默认范围为 jaxws-rt jars(即编译)。

【讨论】:

好吧,如果你使用“编译”范围,你实际上是在你的 WAR 中捆绑了 tose JAR。【参考方案2】:

那么,说 Java 7 附带 Metro.. 是什么意思?

这并不完全正确。 JDK6+ 包括 JAX-WS RI(参考实现),Metro 是它的超集。换句话说,Metro = JAX-WS RI + WSIT。

是否可以在 Tomcat 中运行 JAX-WS Web 服务 Java 自带的 jar 包?

这是一个很好的问题。答案是 - 不,因为WSServlet 类扩展了HttpServlet,而WSServletContextListener 实现了ServletContextAttributeListenerServletContextListener 接口。这些接口和类都是 Java EE 的一部分,而不是 Java SE - 因此不包含在 JDK/JRE 中。 Sun/Oracle 决定不混合使用 Java SE 和 Java EE,尽管这意味着这些类实际上已从 JDK/JRE 附带的 JAX-WS RI 版本中删除,但这是可以理解的。因此,您必须安装 JAX-WS 依赖项才能在 Tomcat 上使用基于 JAX-WS 的 Web 服务,因为 Tomcat 不附带它(另一方面,如果您选择 Glassfish 为例,您会发现完整的 Metro分发与它捆绑在一起,您不必额外安装任何东西)。否则,您将被 Endpoint#publish 机制卡住。

另见:

WSServletContextListener and WSServlet in JRE 6

【讨论】:

【参考方案3】:

捆绑的 JAX-WS 缺乏与 servlet 容器的集成,因为它旨在用于在独立的 Java 应用程序中提供 JAX-WS 服务(WTF!?!?!?)。 p>

当然,人们可以考虑实现一个 servlet 来进行这种集成,这样您就不必在 WAR 中包含另一个 Metro 副本。但是只包含一个外部的“完整”副本更容易,它会使 WAR 膨胀,但不应该有很大的性能损失。此外,通过这种方式,您可以控制使用的版本,避免卡在 JRE 中包含的版本。

无论如何,Sun 通常会更改捆绑库中的包名称,这样它们就不会与外部的冲突,因此,如果 servlet 存在(它不存在),它可能会被调用:

com.sun.xml。 内部。 ws.transport.http.servlet.WSServlet

这很烦人,因为他们还以相同的方式更改了一些配置属性(例如:与超时相关的属性),因此如果您使用捆绑的 JAX-WS,则必须使用

com.sun.xml。 internal....样式配置属性,

但是如果你使用一些外部的 JAX-WS 你必须使用

com.sun.xml....样式配置属性。

谢谢孙!!

【讨论】:

以上是关于Java 中包含的 JAX-WS 实现?的主要内容,如果未能解决你的问题,请参考以下文章

WebService:JAX-WS实现WebService

以Java 8方式检查对象中包含的空对象和空值

JAX-WS服务端及客户端

Spring 整合CXF 实现WebService(JAX-WS)

JAX-WS、Axis2 和 CXF 的区别

如何传递文件中包含的命令行参数并保留该文件的名称?