Tomcat 上的 JAX-WS Web 服务,无需 sun-jaxws.xml

问题描述 投票:0回答:5

我试图在 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
,以及如何避免?

java web-services jakarta-ee tomcat jax-ws
5个回答
15
投票

遗憾的是,配置必须存在于某处。根据消息来源,这是强制性的。不管你相信与否,sun-jaxws.xml 文件的位置已硬编码到 /WEB-INF/sun-jaxws.xml(谢谢@Metro 的朋友们)。

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


需要发生什么:

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

    • 实现您自己的普通 servlet 侦听器(使用

      @WebListener
      )并调用
      new WSServletContextListener()
      。然后,您将自己的
      contextInitialized(ServletContext ctxt)
      contextDestroyed()
      方法委托给
      WSServletContextListener
      实例中的方法。

    • 使用表示 sun-jaxws 文件的

      @XmlRootElement
      类动态生成侦听器实例化的文件(我将在短时间内提供此示例,但没有时间现在:))。

对于这种可有可无的便利来说,这很麻烦,IMO,但理论上它应该有效。我会写一些示例并很快看看它们的表现如何。


4
投票

要在 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>

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();
    }

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 文件。


0
投票

我正在使用 springboot 应用程序,需要在 tomcat 中公开 web 服务(soap) - 你在 2017 年成功了吗 - 我问晚了,我知道,但我现在需要一个可用的 - 在我们使用另一台服务器之前,现在我们使用tomcat - 我们总是创建rest api,但现在希望保持soap服务不变并迁移到spring和tomcat

© www.soinside.com 2019 - 2024. All rights reserved.