2014-01-19 82 views
15

嘗試使用Tomcat 7部署JAX-WS端點Maven插件和CXF 2.7.8。作爲一個優先事項,我不想爲Spring或CXF配置任何XML配置。我看到一些使用cxf-servlet.xml 和CXFServlet的博客,文章和帖子,但沒有完全使用Java配置。查看CXFServlet源代碼,它會查找cxf-servlet.xml或關鍵字'config-location'下servlet上下文中的任何內容。我嘗試以編程方式註冊端點而不是cxf-servlet.xml,但它不起作用;訪問該服務時,我得到一個404。有任何想法嗎?Apache CXF + Spring Java配置(無XML)

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

回答

8

所需要的只是上面的endpoint.publish()調用。

+0

如何在基於java的配置中添加多個端點? –

+0

@HarmeetSingh我還沒有嘗試過,但你有沒有嘗試過創建另一個返回Endpoint的方法? –

+1

是的,我嘗試和它工作正常。 –

1

我相信,如果你通過內部factory.setServiceBeans您的豆子,將工作

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(); 
} 
} 
+1

他要求不要xml ... – Cuga

4

這個線程肯定把我在正確的軌道上得到CXF在純Spring Java配置運行,但它沒」提供所需的一切。

對於我自己,純Java配置意味着沒有web.xml文件,我認爲這個答案假定存在。 Spring Boot例如不使用web.xml文件。

因此,要註冊CXF端點而不使用任何XML文件,您將需要一個配置文件,該文件還會加載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,演示了這一點。

+0

你對註冊「CXFServlet」是正確的。我確實註冊了,但與CXF配置不在同一個地方,因此沒有在我的答案中顯示。 web.xml的Spring Java替代品與CXF無關,如果你需要更多的配置,你將無法像上面那樣做。 web.xml的Spring替代方案是'AbstractAnnotationConfigDispatcherServletInitializer' - [here's](https://github.com/abhijitsarkar/jax-ws/blob/master/jax-ws-instrumentation/src/main/java/name/abhijitsarkar/) webservices/jaxws/instrumentation/config/WebAppInitializer.java)如何做到這一點。 –

+1

但是你正在將xml導入到你的Java中......那個「純Java」怎麼樣? – david

7

這裏發佈的所有東西都不是100%的XML配置免費 - 所有的帖子都使用了classpath:META-INF/cxf/cxf.xml,它也在網絡上的大多數教程中使用。但有一個解決方案:定義一個org.apache.cxf.bus.spring.SpringBus作爲@Bean並配置名稱= Bus.DEFAULT_BUS_ID,來自org.apache.cxf.Bus。

正如其他答案中所述,org.apache.cxf.jaxws.EndpointImpl必須實例化 - 包括轉發Beans SpringBus和SEI實現類。此外,發佈() - EndpointImpl的方法來becalled,包括含有結尾的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在一起,我建議在this github project看看。

+0

這取決於你的意思是「XML免費」。原文是關於配置Java客戶端而不寫XML;沒有人會說通過Java配置不導入XML。導入'cxf.xml'可以讓客戶端不必編寫額外的代碼,而且我總是喜歡在我的代碼中。 –

+1

對我來說,「no XML」意思是說,你使用從Spring 4.x開始的Java配置(包括Spring Boot)來定義Beans。 cxf.xml通過Spring的XML配置定義Beans。順便說一下:導入cxf.xml並聲明Autowired Bean需要3行 - 與「無XML」方法相同:) – jonashackt

+0

「@ImportResource({」classpath:META-INF/cxf/cxf.xml「 })'3行代碼? –

0

如果你使用Spring啓動,你可以使用:

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

Official documentation of the CXF-Boot integration

+0

這是一個4歲的問題,如果他們已經使用Spring Boot,沒有人使用CXF。 –

+0

@Abhijit我不同意。如果問題提出時解決方案不存在,那麼爲舊問題添加新答案沒有任何問題。另外,'cxf-spring-boot-starter-jaxws'的存在表明人們通過Boot使用CXF。 – imgx64