14

在 Tomcat 上部署基于 JAX-WS 的 Web 服务时,我试图最小化所需的配置。随着 Servlet 3.0(Tomcat 7+ 支持)的引入,web.xml可以扔掉,但仍然存在sun-jaxws.xml. 这篇博文很有趣:

当然,通过使用 jax-ws 注释,甚至可以将配置 sun-jaxws.xml 设为可选,使其完全免费,但这需要指定像 JSR-109 中的默认 url-pattern 或像 Jersey REST 中那样的自定义模式服务,在 JAX-WS 规范中。

是否可以sun-jaxws.xml在 Tomcat 上避免,如何避免?

4

4 回答 4

14

可悲的是,配置必须存在于某个地方。根据消息来源,这是强制性的。信不信由你,sun-jaxws.xml 文件的位置被硬编码到 /WEB-INF/sun-jaxws.xml (谢谢@Metro 的伙计们)。

实际上,您需要控制以下类


需要发生的事情:

  1. WSServletContextListener显然不会延长。此侦听器根据 sun-jaxws.xml 和 jaxws-catalog 文件执行大部分初始化。就像我之前提到的,位置是硬编码的。所以你在这里阻力最小的路径是

    • 实现您自己的 vanilla servlet 侦听器(使用@WebListener)并调用new WSServletContextListener(). 然后,您将自己的方法contextInitialized(ServletContext ctxt)contextDestroyed()方法委托给您的实例中的方法WSServletContextListener

    • 使用代表 sun-jaxws 文件的类即时生成侦听器实例化@XmlRootElement文件(我将在短时间内提供此示例,现在没有时间 :)) .

IMO,这种可有可无的便利很麻烦,但理论上它应该可以工作。我会写一些样本,看看它们很快会如何播放。

于 2013-05-22T22:11:29.857 回答
3

要在 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>
于 2017-11-27T09:03:25.503 回答
2

我已经通过这种方式成功发布了 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();
    }
于 2015-06-03T11:51:17.770 回答
1

您必须发布 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 文件。

于 2013-05-22T01:17:08.897 回答