20

尝试使用 Tomcat 7 Maven 插件和 CXF 2.7.8 部署 JAX-WS 端点。作为一个偏好问题,我不想为 Spring 或 CXF 进行任何 XML 配置。我看到一些博客、文章、帖子使用cxf-servlet.xml 和 CXFServlet,但没有一个完全使用 Java 配置。查看 CXFServlet 源代码,它会cxf-servlet.xml在 servlet 上下文中的 key 下查找 或任何内容'config-location'。我尝试以编程方式注册端点而不是 in cxf-servlet.xml,但它不起作用;访问服务时收到 404。有任何想法吗?

@Configuration
@ImportResource({ "classpath:META-INF/cxf/cxf.xml" })
public class CXFConfig {
    @Autowired
    Bus cxfBus;

    // More code

    @Bean
    public Endpoint calculator() {
        EndpointImpl endpoint = new EndpointImpl(cxfBus, new Calculator());
        endpoint.setAddress("/CalculatorService");
        return endpoint;
    }
}
4

5 回答 5

13

此处发布的所有内容都不是 100% 免费的 XML 配置 - 所有帖子都使用类路径:META-INF/cxf/cxf.xml,这也用于网络上的大多数教程。但有一个解决方案:将 org.apache.cxf.bus.spring.SpringBus 定义为 @Bean 并配置 name = Bus.DEFAULT_BUS_ID,来自 org.apache.cxf.Bus。

如其他答案中所述,必须实例化 org.apache.cxf.jaxws.EndpointImpl - 包括 Beans SpringBus 和 SEI 实现类的转发。此外,必须调用 EndpointImpl 的 publish()-Method,包括一个包含 URL 结尾的字符串:

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

如果你想了解更多关于 Apache CXF 和 SpringBoot 的知识,我推荐看看这个 github 项目

于 2016-03-21T16:55:05.887 回答
10

所需要的只是endpoint.publish()上面的一个电话。

于 2014-01-27T15:49:40.510 回答
6

这个线程肯定让我走上了正确的轨道,让 CXF 在纯 Spring Java 配置中运行,但它没有提供所需的一切。

就我自己而言,纯 Java 配置意味着没有web.xml文件,我认为这个答案假设存在。例如,Spring Boot 不使用web.xml文件。

因此,要在不使用任何 XML 文件的情况下注册 CXF 端点,您将需要一个配置文件,该文件还加载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;
    }
}

以上是在 Spring 中成功加载 CXF 端点所需的所有配置。

我还创建了一个小项目来演示这一点。

于 2015-03-15T10:38:52.863 回答
1

我相信如果您在 factory.setServiceBeans 中传递您的 bean,它将起作用

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();
}
}
于 2014-10-30T17:49:13.677 回答
1

如果您使用的是 Spring Boot,则可以使用:

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

添加端点:

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

CXF-Boot 集成的官方文档

于 2017-12-25T08:12:57.040 回答