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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16537821/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 23:15:02  来源:igfitidea点击:

JAX-WS Web service on Tomcat without sun-jaxws.xml

javaweb-servicesjakarta-eetomcatjax-ws

提问by Miljen Mikic

I am trying to minimize required configuration while deploying JAX-WS-based Web service on Tomcat. With the introduction of Servlet 3.0 (supported by Tomcat 7+), web.xmlcan be thrown out, but there is still sun-jaxws.xml. This blog postis interesting:

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

Of course, with the use of jax-ws annotations, even configuration sun-jaxws.xml can be made optional making it completely descriptor free, but that requires specifying a default url-pattern like in JSR-109 or custom pattern like in Jersey REST services, in the JAX-WS specification.

当然,使用 jax-ws 注释,甚至可以将配置 sun-jaxws.xml 设为可选,使其完全没有描述符,但这需要指定一个默认的 url-pattern,如 JSR-109 或自定义模式,如 Jersey REST服务,在 JAX-WS 规范中。

Is it possible to avoid sun-jaxws.xmlon Tomcat, and how?

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

采纳答案by kolossus

Sadly, the configuration mustexist somewhere. That is mandatory, per the source. Believe it or not, the location of the sun-jaxws.xml file is hard-codedto /WEB-INF/sun-jaxws.xml (thanks, guys @ Metro).

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

Effectively, you need to take control of the following classes

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



What needs to happen:

需要发生什么:

  1. WSServletContextListenerwill obviously not be extended. This listener performs most of the initializations per the sun-jaxws.xml and jaxws-catalog file. Like I mentioned earlier, the location is hard coded. So your path of least resistance here is to

    • implement your own vanilla servlet listener (with @WebListener) and call a new WSServletContextListener(). You'll then delegate your own contextInitialized(ServletContext ctxt)and contextDestroyed()methods to the ones in your instance of WSServletContextListener.

    • Generate the file on instantiation of the listener, on the fly, using an @XmlRootElementclass that'll represent the sun-jaxws file(I'll provide a sample of this in a short while, don't have the time right now :) ).

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

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

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

It's a lot of trouble for such a dispensable convenience, IMO, but it should work in theory. I'll write some samples and see how they play shortly.

对于这种可有可无的便利,IMO,这很麻烦,但理论上应该可行。我会写一些样本,看看他们很快就会发挥作用。

回答by Adrian Malik

To have JAX-WS support in Tomcat you must configure:

要在 Tomcat 中获得 JAX-WS 支持,您必须配置:

  • WEB-INF/sun-jaxws.xml
  • WSServletContextListener
  • WSServlet
  • WEB-INF/sun-jaxws.xml
  • WSServletContextListener
  • 服务小程序

Unfortunately it is hard to omit the WEB-INF/sun-jaxws.xmlfile but there is easier way to omit web.xmlconfiguration because of Servlet 3.0 API.

不幸的是,很难省略WEB-INF/sun-jaxws.xml文件,但是由于 Servlet 3.0 API,有一种更简单的方法可以省略web.xml配置。

You can do something like this:

你可以这样做:

@WebServlet(name = "ServiceServlet" , urlPatterns = "/service", loadOnStartup = 1)
public class Servlet extends WSServlet {

}

and

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

I have tested it on Tomcat-8.5.23 version and it works. But remember that you still must have WEB-INF/sun-jaxws.xmlfile.

我已经在 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>

回答by yunus kula

I have publised web services successfully by this way. I have used apache cfx for publishing in servletContextListener.

我已经通过这种方式成功发布了网络服务。我已经使用 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();
    }

回答by Michael Henrique

You have to publish the web service. You can implement a ServletContextListener and publish the endpoint:

您必须发布 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 is not mandatory by specs...If you note, for example, glassfish (metro) makes it optional. Also, if you expose a EJB 3.1 as webservice (with jaxws) you can see no sun-jaxws.xml file in the generated build.

sun-jaxws.xml 不是规范所必需的……例如,如果您注意到 glassfish(metro)使其成为可选的。此外,如果您将 EJB 3.1 公开为 web 服务(使用 jaxws),您在生成的构建中看不到 sun-jaxws.xml 文件。