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

前端 未结 4 2098
礼貌的吻别
礼貌的吻别 2021-02-13 12:02

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.xml

相关标签:
4条回答
  • 2021-02-13 12:51

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

    @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.

    0 讨论(0)
  • 2021-02-13 13:00

    I have publised web services successfully by this way. I have used apache cfx for publishing in 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();
        }
    
    0 讨论(0)
  • 2021-02-13 13:01

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

    • WEB-INF/sun-jaxws.xml
    • WSServletContextListener
    • WSServlet

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

    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.xml file.

    <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>
    
    0 讨论(0)
  • 2021-02-13 13:03

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

    Effectively, you need to take control of the following classes

    • public final class WSServletContextListener

    • public class WSServlet


    What needs to happen:

    1. WSServletContextListener will 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 @XmlRootElement class 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 :) ).

    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.

    0 讨论(0)
提交回复
热议问题