[英]JAX-WS Web service on Tomcat without sun-jaxws.xml
我正在尝试在Tomcat上部署基于JAX-WS的Web服务时最小化所需的配置。 随着Servlet 3.0的引入(由Tomcat 7+支持), web.xml
可以被抛弃,但仍然存在sun-jaxws.xml
。 这篇博文很有意思:
当然,通过使用jax-ws注释,甚至可以使配置sun-jaxws.xml成为可选的,使其完全无描述符,但这需要指定一个默认的url-pattern,如JSR-109或自定义模式,如Jersey REST服务,在JAX-WS规范中。
是否有可能在Tomcat上避免使用sun-jaxws.xml
,以及如何实现?
可悲的是,配置必须存在于某处 。 根据消息来源,这是强制性的。 信不信由你, sun-jaxws.xml文件的位置被硬编码到/WEB-INF/sun-jaxws.xml(感谢,guys @ Metro)。
实际上,您需要控制以下类
需要做什么:
WSServletContextListener
显然不会被扩展。 此侦听器根据sun-jaxws.xml和jaxws-catalog文件执行大多数初始化。 就像我之前提到的,位置是硬编码的。 所以你的阻力最小的路径是
实现自己的vanilla servlet监听器(使用@WebListener
)并调用new WSServletContextListener()
。 然后,您将自己的contextInitialized(ServletContext ctxt)
和contextDestroyed()
方法委托给contextInitialized(ServletContext ctxt)
实例中的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公开为webservice(使用jaxws),则可以在生成的构建中看不到sun-jaxws.xml文件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.