尝试使用Tomcat 7 Maven插件和CXF 2.7.8部署JAX-WS端点。作为优先选择,我不想为Spring或CXF提供任何XML配置。我看到几个博客,文章,帖子使用cxf-servlet.xml
和CXFServlet,但没有任何完全使用Java配置。查看CXFServlet源代码,它会在密钥cxf-servlet.xml
下查找'config-location'
或servlet上下文中的任何内容。我尝试以编程方式注册端点而不是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;
}
}
所需要的只是上面的endpoint.publish()
电话。
这里发布的所有内容都不是100%免费的XML配置 - 所有帖子都使用类路径:META-INF / cxf / cxf.xml,它也用于Web上的大多数教程。但有一个解决方案:将org.apache.cxf.bus.spring.SpringBus定义为@Bean并配置name = Bus.DEFAULT_BUS_ID,来自org.apache.cxf.Bus。
如其他答案中所述,必须实例化org.apache.cxf.jaxws.EndpointImpl - 包括转发Beans SpringBus和SEI实现类。此外,必须使用publish() - EndpointImpl方法,包括一个包含URL结尾的String:
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的更多信息,我建议您查看this github project。
这个线程肯定让我在正确的轨道上让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端点所需的所有配置。
我还创建了一个small project来证明这一点。
我相信如果你在factory.set ServiceBeans中传递你的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();
}
}
如果您使用的是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;
}
}