我试图在 Tomcat 上部署基于 JAX-WS 的 Web 服务时尽量减少所需的配置。随着Servlet 3.0的引入(Tomcat 7+支持),
web.xml
可以被扔掉了,但是sun-jaxws.xml
仍然存在。这篇博客文章很有趣:
当然,有了jax-ws注解的使用,甚至配置 sun-jaxws.xml 可以是可选的,使其成为完全描述符 免费,但这需要指定一个默认的 url 模式,如 JSR-109 或自定义模式,如 Jersey REST 服务、JAX-WS 中 规格。
是否可以在 Tomcat 上避免
sun-jaxws.xml
,以及如何避免?
遗憾的是,配置必须存在于某处。根据消息来源,这是强制性的。不管你相信与否,sun-jaxws.xml 文件的位置已硬编码到 /WEB-INF/sun-jaxws.xml(谢谢@Metro 的朋友们)。
实际上,您需要控制以下类
需要发生什么:
WSServletContextListener
显然不会延长。此侦听器根据 sun-jaxws.xml 和 jaxws-catalog 文件执行大部分初始化。正如我之前提到的,位置是硬编码的。因此,阻力最小的路径是
实现您自己的普通 servlet 侦听器(使用
@WebListener
)并调用 new WSServletContextListener()
。然后,您将自己的 contextInitialized(ServletContext ctxt)
和 contextDestroyed()
方法委托给 WSServletContextListener
实例中的方法。 使用表示 sun-jaxws 文件的
@XmlRootElement
类动态生成侦听器实例化的文件(我将在短时间内提供此示例,但没有时间现在:))。对于这种可有可无的便利来说,这很麻烦,IMO,但理论上它应该有效。我会写一些示例并很快看看它们的表现如何。
要在 Tomcat 中获得 JAX-WS 支持,您必须配置:
不幸的是,很难省略 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服务。我已经使用 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();
}
您必须发布 Web 服务。您可以实现 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 文件。
我正在使用 springboot 应用程序,需要在 tomcat 中公开 web 服务(soap) - 你在 2017 年成功了吗 - 我问晚了,我知道,但我现在需要一个可用的 - 在我们使用另一台服务器之前,现在我们使用tomcat - 我们总是创建rest api,但现在希望保持soap服务不变并迁移到spring和tomcat