没有 sun-jaxws.xml 的 Tomcat 上的 JAX-WS Web 服务
Posted
技术标签:
【中文标题】没有 sun-jaxws.xml 的 Tomcat 上的 JAX-WS Web 服务【英文标题】:JAX-WS Web service on Tomcat without sun-jaxws.xml 【发布时间】:2013-05-08 10:01:35 【问题描述】:在 Tomcat 上部署基于 JAX-WS 的 Web 服务时,我试图最小化所需的配置。随着 Servlet 3.0(Tomcat 7+ 支持)的引入,web.xml
可以被扔掉,但sun-jaxws.xml
仍然存在。这个blog post很有意思:
当然,使用 jax-ws 注解,甚至配置 sun-jaxws.xml 可以成为可选的,使其成为完全描述符 免费,但这需要指定一个默认的 url 模式,如 JSR-109 或 JAX-WS 中的 Jersey REST 服务中的自定义模式 规范。
是否可以在 Tomcat 上避免 sun-jaxws.xml
,以及如何避免?
【问题讨论】:
【参考方案1】:遗憾的是,配置必须存在于某处。根据消息来源,这是强制性的。信不信由你,the location of the sun-jaxws.xml file is hard-coded 到 /WEB-INF/sun-jaxws.xml(谢谢,伙计们@Metro)。
实际上,您需要控制以下类
public final class WSServletContextListener
public class WSServlet
需要做什么:
WSServletContextListener
显然不会被扩展。此侦听器根据 sun-jaxws.xml 和 jaxws-catalog 文件执行大部分初始化。就像我之前提到的,位置是硬编码的。所以你在这里阻力最小的路径是
实现您自己的 vanilla servlet 侦听器(使用@WebListener
)并调用new WSServletContextListener()
。然后,您将自己的contextInitialized(ServletContext ctxt)
和contextDestroyed()
方法委托给WSServletContextListener
实例中的方法。
使用代表 sun-jaxws 文件的 @XmlRootElement
类即时生成监听器实例化文件(我将在短时间内提供此示例,不要'现在没时间 :) )。
IMO,这种可有可无的便利很麻烦,但理论上它应该可以工作。我会写一些样本,看看它们的播放效果。
【讨论】:
+1,不知道sun-jaxws.xml
的位置是硬编码的 :) 默认 url 模式应该使 sun-jaxws.xml
可选(请参阅我在我的问题),你知道吗?
@MiljenMikic 仔细阅读那篇文章,这一切似乎都是一厢情愿,没有太多参考:他博客文章中的链接已失效。我仍然设法找到了他所指的来源 here 和 readme.txt 仍然表明 sun-jaxws.xml 是必要的【参考方案2】:
要在 Tomcat 中获得 JAX-WS 支持,您必须配置:
WEB-INF/sun-jaxws.xml WSServletContextListener WSServlet不幸的是,很难省略 WEB-INF/sun-jaxws.xml 文件,但由于 Servlet 3.0 API,有更简单的方法可以省略 web.xml 配置.
你可以这样做:
@WebServlet(name = "ServiceServlet" , urlPatterns = "/service", loadOnStartup = 1)
public class Servlet extends WSServlet
和
@WebListener
public class Listener implements ServletContextAttributeListener, ServletContextListener
private final WSServletContextListener listener;
public Listener()
this.listener = new WSServletContextListener();
@Override
public void attributeAdded(ServletContextAttributeEvent event)
listener.attributeAdded(event);
@Override
public void attributeRemoved(ServletContextAttributeEvent event)
listener.attributeRemoved(event);
@Override
public void attributeReplaced(ServletContextAttributeEvent event)
listener.attributeReplaced(event);
@Override
public void contextInitialized(ServletContextEvent sce)
listener.contextInitialized(sce);
@Override
public void contextDestroyed(ServletContextEvent sce)
listener.contextDestroyed(sce);
我已经在 Tomcat-8.5.23 版本上对其进行了测试,并且可以正常工作。但请记住,您仍然必须有 WEB-INF/sun-jaxws.xml 文件。
<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime"
version="2.0">
<endpoint name="SampleService"
implementation="com.ws.ServiceImpl"
url-pattern="/service" />
</endpoints>
【讨论】:
我知道我们可以省略web.xml
文件,这在问题的文本中已经提到过。问题是关于省略 sun-jaxws.xml
文件。
啊,好吧,但我为其他可能不知道如何为这个问题省略 web.xml 文件的人添加了解决方案。例如,几周前我遇到了这个问题。
有什么方法可以在这个xml配置中指定端口吗?【参考方案3】:
我已经通过这种方式成功发布了 Web 服务。我使用 apache cfx 在 servletContextListener 中发布。
@WebListener
public class WebServicePublisListener implements ServletContextListener
/**
* Default constructor.
*/
public WebServicePublisListener()
// TODO Auto-generated constructor stub
/**
* @see ServletContextListener#contextInitialized(ServletContextEvent)
*/
public void contextInitialized(ServletContextEvent sce)
JaxWsServerFactoryBean srvFactory = new JaxWsServerFactoryBean();
srvFactory.setServiceClass(RandService.class);
srvFactory.setAddress("/RandService");
srvFactory.setServiceBean(new RandServiceImplement());
srvFactory.create();
【讨论】:
感谢您的回答。我应该用“JAX-WS RI”或“Metro”标签标记我的问题,因为sun-jaxws.xml
与这些实现有关。 Apache CXF 是 JAX-WS 的不同实现,所以它与sun-jaxws.xml
没有任何关系。【参考方案4】:
您必须发布网络服务。您可以实现 ServletContextListener 并发布端点:
@javax.servlet.annotation.WebListener
public class AppServletContextListener implements javax.servlet.ServletContextListener
public void contextInitialized(ServletContextEvent sce)
Endpoint.publish("protocol://host:port/context/wsName", new MyHelloWorldWSImpl());
public void contextDestroyed(ServletContextEvent sce)
....
sun-jaxws.xml 在规范中不是强制性的...如果您注意到,例如,glassfish (metro) 将其设为可选。此外,如果您将 EJB 3.1 公开为 Web 服务(使用 jaxws),您将在生成的构建中看不到 sun-jaxws.xml 文件。
【讨论】:
感谢您的回答。但是,我不想使用 Endpoint.publish(..) 基础架构,因为它代表了一个轻量级 HTTP 服务器——如果我想要的话,我就不会使用 Tomcat。接下来,Tomcat是一个servlet容器;换句话说,您不能在 Tomcat 上部署 EJB。我知道这在 Glassfish 中就像一个魅力,但那是因为 Glassfish 符合 JSR-109。 Tomcat 默认不支持 EJB。例如,您应该考虑使用 TomEE。我提到 EJB 只是为了作为一个例子来证明不需要 sun-jaxws.xml(它不是强制性的)。 就个人而言,我总是更喜欢完整的应用程序服务器(例如 Glassfish)而不是 servlet 容器(例如 Tomcat)。但是,我们的客户使用 Tomcat,我很好奇是否可以简化在 Tomcat 上部署 Web 服务所需的配置。因此,我的问题专门针对 Tomcat,而不是 TomEE 或 Glassfish。以上是关于没有 sun-jaxws.xml 的 Tomcat 上的 JAX-WS Web 服务的主要内容,如果未能解决你的问题,请参考以下文章