Apache CXF + Spring Java config (no XML)

前端 未结 5 2136
孤城傲影
孤城傲影 2020-12-15 19:05

Trying to deploy a JAX-WS endpoint using Tomcat 7 Maven plugin and CXF 2.7.8. As a matter of preference, I don\'t want to have any XML config for Spring or CXF. I see severa

相关标签:
5条回答
  • 2020-12-15 19:44

    If you're using Spring Boot, you can use:

    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-spring-boot-starter-jaxws</artifactId>
        <version>${cxf.version}</version> <!-- 3.1.7 or higher -->
    </dependency>
    

    To add an endpoint:

    import javax.xml.ws.Endpoint;
    import org.apache.cxf.Bus;
    import org.apache.cxf.jaxws.EndpointImpl;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class WebServiceConfig {
    
        @Bean
        public Endpoint endpoint(Bus cxfBus) {
            EndpointImpl endpoint = new EndpointImpl(cxfBus, new Calculator());
            endpoint.publish("/CalculatorService");
            return endpoint;
        }
    }
    

    Official documentation of the CXF-Boot integration.

    0 讨论(0)
  • 2020-12-15 19:51

    All that's needed is a endpoint.publish() call above.

    0 讨论(0)
  • 2020-12-15 19:51

    I belive that if you pass your beans inside factory.setServiceBeans it will work

    package br.com.app.spring;
    
    import java.util.Arrays;
    
    import javax.ws.rs.ext.RuntimeDelegate;
    
    import org.apache.cxf.bus.spring.SpringBus;
    import org.apache.cxf.endpoint.Server;
    import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
    import org.codehaus.jackson.jaxrs.JacksonJsonProvider;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.ImportResource;
    
    import br.com.app.JaxRsApiApplication;
    import br.com.app.services.EditionRest;
    import br.com.app.services.EditionService;
    
    @Configuration
    @ImportResource(
        { 
            "classpath:META-INF/cxf/cxf.xml", 
            "classpath:META-INF/cxf/cxf-extension-xml.xml",
            "classpath:META-INF/cxf/cxf-servlet.xml" 
        })
    public class CXFConfig {
    
    @Bean(destroyMethod = "shutdown")
    public SpringBus cxf() {
        return new SpringBus();
    }
    
    @Bean
    public EditionService editionRest() {
        return new EditionRest();
    }
    
    @Bean
    public JaxRsApiApplication jaxRsApiApplication() {
        return new JaxRsApiApplication();
    }
    
    @Autowired
    @Bean
    public Server jaxRsServer(JacksonJsonProvider provider) {
    
        JAXRSServerFactoryBean factory = RuntimeDelegate.getInstance().createEndpoint(jaxRsApiApplication(), JAXRSServerFactoryBean.class);
        factory.setServiceBeans(Arrays.<Object> asList(editionRest()));
        factory.setProviders(Arrays.<Object> asList(provider));
    
        return factory.create();
    }
    
    @Bean
    public JacksonJsonProvider jsonProvider() {
        return new JacksonJsonProvider();
    }
    }
    
    0 讨论(0)
  • 2020-12-15 19:53

    Everything posted here is not 100% XML configuration free - all posts are using the classpath:META-INF/cxf/cxf.xml, which is also used in most tutorials on the web. But there´s a solution for that: Define a org.apache.cxf.bus.spring.SpringBus as @Bean and configure name = Bus.DEFAULT_BUS_ID, comming from org.apache.cxf.Bus.

    As described in the other answers, the org.apache.cxf.jaxws.EndpointImpl has to be instantiated - including forwarding of the Beans SpringBus and the SEI-implementing Class. Also, the publish()-Method of EndpointImpl has to becalled, including a String containing an URL ending:

    package de.jonashackt.tutorial.configuration;
    
    import javax.xml.ws.Endpoint;
    
    import org.apache.cxf.Bus;
    import org.apache.cxf.bus.spring.SpringBus;
    import org.apache.cxf.jaxws.EndpointImpl;
    import org.apache.cxf.transport.servlet.CXFServlet;
    import org.springframework.boot.context.embedded.ServletRegistrationBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import de.codecentric.namespace.weatherservice.WeatherService;
    import de.jonashackt.tutorial.endpoint.WeatherServiceEndpoint;
    
    @Configuration
    public class WebServiceConfiguration {
    
        @Bean
        public ServletRegistrationBean dispatcherServlet() {
            return new ServletRegistrationBean(new CXFServlet(), "/soap-api/*");
        }
    
        @Bean(name = Bus.DEFAULT_BUS_ID)
        public SpringBus springBus() {
            return new SpringBus();
        }    
    
        @Bean
        public WeatherService weatherService() {
            return new WeatherServiceEndpoint();
        }
    
        @Bean
        public Endpoint endpoint() {
            EndpointImpl endpoint = new EndpointImpl(springBus(), weatherService());
            endpoint.publish("/WeatherSoapService");
            return endpoint;
        }
    }
    

    If you want to learn more about Apache CXF together with SpringBoot, I recommend a look on this github project.

    0 讨论(0)
  • 2020-12-15 19:53

    This thread definitely put me on the right track to getting CXF to run in pure Spring Java configuration, but it didn't provide everything that is required.

    For my self, pure Java configuration means without a web.xml file, which I think this answer assumes is present. Spring Boot for example doesn't use a web.xml file.

    So to register a CXF endpoint without the use of any XML files at all you will need a configuration file that also loads the CXFServlet.

    import org.apache.cxf.Bus;
    import org.apache.cxf.jaxws.EndpointImpl;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.ImportResource;
    
    import javax.xml.ws.Endpoint;
    
    @Configuration
    @ImportResource({"classpath:META-INF/cxf/cxf.xml"})
    public class JavaConfiguration {
    
        @Autowired
        private Bus bus;
    
        @Bean
        public Endpoint myServiceEndpoint() {
            EndpointImpl endpoint = new EndpointImpl(bus, new MyService());
            endpoint.publish("/myservice");
            return endpoint;
        }
    
        @Bean
        public ServletRegistrationBean cxfServlet() {
            ServletRegistrationBean servlet = new ServletRegistrationBean(new CXFServlet(), "/services/*");
            servlet.setLoadOnStartup(1);
            return servlet;
        }
    }
    

    The above is all the configuration required to successfully load a CXF endpoint within Spring.

    I have also created a small project that demonstrates this.

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