Springを使用したApacheCXFのガイド

1。概要

このチュートリアルでは、Apache CXFフレームワークをSpringと一緒に、JavaまたはXML構成で構成および使用することに焦点を当てています。

これは、ApacheCXFに関するシリーズの2番目です。1つ目は、JAX-WS標準APIの実装としてのCXFの基本に焦点を当てたものです。

2.Mavenの依存関係

前のチュートリアルと同様に、次の2つの依存関係を含める必要があります。

 org.apache.cxf cxf-rt-frontend-jaxws 3.1.6   org.apache.cxf cxf-rt-transports-http 3.1.6 

Apache CXFアーティファクトの最新バージョンについては、apache-cxfを確認してください。

さらに、Springをサポートするには、次の依存関係が必要です。

 org.springframework spring-context 4.3.1.RELEASE   org.springframework spring-webmvc 4.3.1.RELEASE 

Springアーティファクトの最新バージョンはここにあります。

最後に、従来のweb.xmlデプロイメント記述子の代わりにJava Servlet 3.0+ APIを使用してアプリケーションをプログラムで構成するため、以下のアーティファクトが必要になります。

 javax.servlet javax.servlet-api 3.1.0 

ここで、サーブレットAPIの最新バージョンを見つけることができます。

3.サーバー側コンポーネント

ここで、Webサービスエンドポイントを公開するためにサーバー側に存在する必要があるコンポーネントを見てみましょう。

3.1。WebApplicationInitilizerインターフェース

WebApplicationInitializerのインタフェースは、プログラムで設定するために実装されているのServletContextアプリケーションのためのインタフェース。クラスパスに存在する場合、そのonStartupメソッドはサーブレットコンテナによって自動的に呼び出され、その後、ServletContextがインスタンス化されて初期化されます。

WebApplicationInitializerインターフェースを実装するためのクラスの定義方法は次のとおりです。

public class AppInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext container) { // Method implementation } }

onStartup()メソッドは、以下に示すコードスニペットを使用して実装されています。

最初に、Springアプリケーションコンテキストが作成され、構成メタデータを含むクラスを登録するように構成されます。

AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); context.register(ServiceConfiguration.class);

サービス構成クラスがで注釈され@ConfigurationのBean定義を提供する注釈。このクラスについては、次のサブセクションで説明します。

次のスニペットは、Springアプリケーションコンテキストがサーブレットコンテキストに追加される方法を示しています。

container.addListener(new ContextLoaderListener(context));

CXFServletのはApache CXFで定義されたクラスは、生成され、着信要求を処理するために登録されています。

ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new CXFServlet());

アプリケーションコンテキストは、構成ファイルで定義されたSpring要素をロードします。この場合、サーブレットの名前はcxfであるため、コンテキストはデフォルトでcxf-servlet.xmlという名前のファイルでこれらの要素を検索します。

最後に、CXFサーブレットは相対URLにマップされます。

dispatcher.addMapping("/services");

3.2。古き良きweb.xml

または、WebApplicationInitilizerインターフェイスではなく(やや古風な)デプロイメント記述子を使用する場合は、対応するweb.xmlファイルに次のサーブレット定義を含める必要があります。

 cxf org.apache.cxf.transport.servlet.CXFServlet 1   cxf /services/* 

3.3。ServiceConfigurationクラス

ここで、サービス構成を見てみましょう。最初に、WebサービスエンドポイントのBean定義を囲む基本的なスケルトンです。

@Configuration public class ServiceConfiguration { // Bean definitions }

最初に必要なBeanはSpringBusです。これは、ApacheCXFがSpringFrameworkと連携するための拡張機能を提供します。

@Bean public SpringBus springBus() { return new SpringBus(); }

EnpointImplの豆も使用して作成する必要がありSpringBusの豆とWebサービスの実装を。このBeanは、指定されたHTTPアドレスでエンドポイントを公開するために使用されます。

@Bean public Endpoint endpoint() { EndpointImpl endpoint = new EndpointImpl(springBus(), new BaeldungImpl()); endpoint.publish("//localhost:8080/services/baeldung"); return endpoint; }

BaeldungImplのクラスは、Webサービスのインタフェースを実装するために使用されます。その定義は次のサブセクションで与えられます。

または、XML構成ファイルでサーバーエンドポイントを宣言することもできます。具体的には、以下のcxf-servlet.xmlファイルは、サブセクション3.1で定義されたweb.xmlデプロイメント記述子で機能し、まったく同じエンドポイントを記述します。

XML構成ファイルは、デプロイメント記述子で定義されているサーブレット名(cxf)にちなんで名付けられていることに注意してください。

3.4. Type Definitions

Next – here is the definition of the implementor that has already been mentioned in the preceding subsection:

@WebService(endpointInterface = "com.baeldung.cxf.spring.Baeldung") public class BaeldungImpl implements Baeldung { private int counter; public String hello(String name) { return "Hello " + name + "!"; } public String register(Student student) { counter++; return student.getName() + " is registered student number " + counter; } }

This class provides an implementation for the Baeldung endpoint interface that Apache CXF will include in the published WSDL metadata:

@WebService public interface Baeldung { String hello(String name); String register(Student student); }

Both the endpoint interface as well as the implementor make use of the Student class, which is defined as follows:

public class Student { private String name; // constructors, getters and setters }

4. Client-Side Beans

To take advantage of the Spring Framework, we declare a bean in a @Configuration annotated class:

@Configuration public class ClientConfiguration { // Bean definitions }

A bean with the name of client is defined:

@Bean(name = "client") public Object generateProxy() { return proxyFactoryBean().create(); }

The client bean represents a proxy for the Baeldung web service. It is created by an invocation to the create method on a JaxWsProxyFactoryBean bean, a factory for the creation of JAX-WS proxies.

The JaxWsProxyFactoryBean object is created and configured by the following method:

@Bean public JaxWsProxyFactoryBean proxyFactoryBean() { JaxWsProxyFactoryBean proxyFactory = new JaxWsProxyFactoryBean(); proxyFactory.setServiceClass(Baeldung.class); proxyFactory.setAddress("//localhost:8080/services/baeldung"); return proxyFactory; }

The factory's serviceClass property denotes the web service interface, while the address property indicates the URL address for the proxy to make remote invocations.

Also for the Spring beans on the client side one may revert to an XML configuration file. The following elements declare the same beans as the ones we just have programmatically configured above:

5. Test Cases

This section describes test cases used to illustrate Apache CXF support for Spring. The test cases are defined in a class named StudentTest.

First, we need to load a Spring application context from the aforementioned ServiceConfiguration configuration class and cache it in the context field:

private ApplicationContext context = new AnnotationConfigApplicationContext(ClientConfiguration.class);

Next, a proxy for the service endpoint interface is declared and loaded from the application context:

private Baeldung baeldungProxy = (Baeldung) context.getBean("client");

This Baeldung proxy will be used in test cases described below.

In the first test case, we prove that when the hello method is locally invoked on the proxy, the response is exactly the same as what the endpoint implementor returns from the remote web service:

@Test public void whenUsingHelloMethod_thenCorrect() { String response = baeldungProxy.hello("John Doe"); assertEquals("Hello John Doe!", response); }

In the second test case, students register for Baeldung courses by locally invoking the register method on the proxy, which in turn calls the web service. That remote service will then calculate the student numbers and return them to the caller. The following code snippet confirms what we expect:

@Test public void whenUsingRegisterMethod_thenCorrect() { Student student1 = new Student("Adam"); Student student2 = new Student("Eve"); String student1Response = baeldungProxy.register(student1); String student2Response = baeldungProxy.register(student2); assertEquals("Adam is registered student number 1", student1Response); assertEquals("Eve is registered student number 2", student2Response); }

6. Integration Testing

In order to be deployed as a web application on a server, code snippets in this tutorial need to be packaged into a WAR file first. This can be achieved by declaring the packaging property in the POM file:

war

The packaging job is implemented by the Maven WAR plugin:

 maven-war-plugin 2.6  false  

This plugin packages the compiled source code into a WAR file. Since we configure the servlet context using Java code, the traditional web.xml deployment descriptor does not need to be existent. As the result, the failOnMissingWebXml property must be set to false to avoid failure when the plugin is executed.

We can follow this link for the most recent version of the Maven WAR plugin.

In order to illustrate operations of the web service, we create an integration test. This test first generates a WAR file and starts an embedded server, then makes clients invoke the web service, verifies subsequent responses and finally stops the server.

The following plugins need to be included in the Maven POM file. For more details, please check out this Integration Testing tutorial.

Here is the Maven Surefire plugin:

 maven-surefire-plugin 2.19.1   StudentTest.java   

The latest version of this plugin can be found here.

A profile section with the id of integration is declared to facilitate the integration test:

  integration   ...    

The Maven Cargo plugin is included in the integration profile:

 org.codehaus.cargo cargo-maven2-plugin 1.5.0   jetty9x embedded    localhost 8080      start-server pre-integration-test  start    stop-server post-integration-test  stop    

Note that the cargo.hostname and cargo.servlet.port configuration properties are merely included for the sake of clarity. These configuration properties may be left out without any impact on the application since their values are the same as the default values. This plugin starts the server, waits for connections and finally stops the server to release system resources.

This link allows us to check out the latest version of the Maven Cargo plugin.

Maven Surefireプラグインは、統合プロファイル内で再度宣言され、メインビルドセクションの構成をオーバーライドし、前のセクションで説明したテストケースを実行します。

 maven-surefire-plugin 2.19.1   integration-test  test    none     

これで、プロセス全体を次のコマンドで実行できます。mvn-Pintegration cleaninstall

7.結論

このチュートリアルでは、Springに対するApacheCXFのサポートについて説明しました。特に、Spring構成ファイルを使用してWebサービスを公開する方法と、別の構成ファイルで宣言されたApacheCXFプロキシファクトリによって作成されたプロキシを介してクライアントがそのサービスと対話する方法が示されています。

これらすべての例とコードスニペットの実装は、リンクされたGitHubプロジェクトにあります。