web-dev-qa-db-ja.com

Apache CXF + Spring Java構成(XMLなし)

Tomcat 7 MavenプラグインとCXF 2.7.8を使用してJAX-WSエンドポイントをデプロイしようとしています。好みの問題として、SpringやCXFのXML構成は必要ありません。 cxf-servlet.xmlとCXFServletを使用しているブログ、記事、投稿がいくつかありますが、Java configを完全に使用しているものはありません。CXFServletソースコードを見ると、cxf-servlet.xmlを探しています。またはキー'config-location'の下のサーブレットコンテキストにあるもの。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;
    }
}
18
Abhijit Sarkar

必要なのは、上記のendpoint.publish()呼び出しだけです。

10
Abhijit Sarkar

ここに投稿されたものはすべて100%XML設定が無料ではありません。すべての投稿はclasspath:META-INF/cxf/cxf.xmlを使用しています。これは、Web上のほとんどのチュートリアルでも使用されています。しかし、その解決策があります。org.Apache.cxf.Busから来るorg.Apache.cxf.bus.spring.SpringBusを@Beanとして定義し、name = Bus.DEFAULT_BUS_IDを構成します。

他の回答で説明されているように、org.Apache.cxf.jaxws.EndpointImplは、Beans SpringBusおよびSEI実装クラスの転送を含めてインスタンス化する必要があります。また、EndpointImplのpublish()メソッドは、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;
    }
}

SpringBootと一緒にApache CXFについて詳しく知りたい場合は、 このgithubプロジェクト を参照することをお勧めします。

9
jonashackt

このスレッドにより、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エンドポイントを正常にロードするために必要なすべての構成です。

これを示す 小規模プロジェクト も作成しました。

6
Karl Bennett

Beanを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
arthurfnsc

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統合の公式ドキュメント

0
imgx64