はじめに
本記事では、Apache CamelとApache CXFを組み合わせて、Javaコードファーストで作成したSOAP受信アプリを扱う。
下記の背景があり、情報共有として記事を作成した。
- Java、Apache Camel、Apache CXFの使用経験がなく、学習内容の定着を目的のアウトプット
- GitHub上のApache Camelの公式サンプル に、Apache CamelとApache CXFを組み合わせたサンプルが存在しない
- ネットでApache CamelとApache CXFについて検索したとき、ヒットする情報が少ないうえに、古い(リンク切れもある)
- ネットでApache Camel&Apache CXF& Springboot(あるいはSpring)を組み合わせたサンプルはヒットするが、組み合わせが増えると複雑化するので、今回はApache Camel&Apache CXFの組み合わせで振る舞いの理解を深めたい。
実行環境
- Eclipse (4.32.0)
- Maven (3.9.7)
- Java 17(執筆時点の最新バージョンのApache Camelを使用する際に、このバージョンが必要)
- SoapUI (5.7.2)
実装の流れ
依存関係を設定する
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>java.camel.soap.example</groupId>
<artifactId>camel-example-cxf-soap</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>soap example</name>
<description>An example which demonstrates the use of the Camel CXF
component</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<camel.version>4.7.0</camel.version>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.apache.camel/camel-core -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-cxf-soap</artifactId>
<!-- use the same version as your Camel core version -->
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>4.0.4</version>
</dependency>
</dependencies>
</project>
propertiesタグについて
- EclipseのデフォルトのランタイムがJava 8のため、Java 17を使用するようにコンパイラ設定を追加(参考)
dependenciesタグについて
- Apache Camelを適用するために、Maven Reposityよりcamel-core を指定した(2024/08/14時点の最新)
- Apache CamelのCXFコンポーネントを適用する
- 「cxf-rt-transports-http-jetty」を依存に追加する。追加しない場合、実行時エラーになる(※)
※ Apache CXF>Maven POM Informationによれば、「Jetty is needed if you're are not using the CXFServlet」とのこと。「cxf-rt-transports-http-jetty」のバージョンは「cxf-rt-frontend-jaxws」、「cxf-rt-transports-http」に合わせた。
service endpoint interface (SEI)を作成する
以下のようにJava標準のインターフェースを定義すれば良い。
package example;
import jakarta.jws.WebParam;
import jakarta.jws.WebService;
@WebService
public interface HelloWorld {
String sayHi(@WebParam(name = "text") String text);
}
サービス定義のマッピングの際にメタデータとして活用するため、アノテーションを指定する必要がある。
Apache CXF>Developing a Service using JAX-WS#Java First Developmentに、詳細な記載がある。
サービスの実装クラスを作成する
package example;
import jakarta.jws.WebService;
@WebService
public class HelloWorldImpl implements HelloWorld{
@Override
public String sayHi(String text) {
return "Hello " + text;
}
}
ルーティングの設定を実装する
package example;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
public class SoapRouteBuilder extends RouteBuilder{
private static final String SOAP_ENDPOINT_URI = "cxf://http://localhost:9006/soap"
+ "?serviceClass=example.HelloWorld";
private Processor proc;
SoapRouteBuilder(Processor proc){
this.proc = proc;
}
@Override
public void configure() throws Exception {
System.out.println("Starting Server");
from(SOAP_ENDPOINT_URI)
.process(this.proc);
}
}
以下の部分が、Apache CamelとApache CXFの紐づけを行っている箇所。
cxf://http://localhost:9006/soap?serviceClass=example.HelloWorld
「cxf://http://localhost:9006/soap」の部分は、Apache CamelのCXFコンポーネントのURIフォーマット(下記)に従って記述した。
cxf://someAddress[?options]
Where someAddress specifies the CXF endpoint’s address. With this URI format, >most of the endpoint details are specified using options.
続いて、クエリパラメータであるserviceClassを用いて、AddressとSEIを紐づけした。
メッセージ受信時の処理を実装する
package example;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
public class SoapProcessor implements Processor {
private HelloWorld instance;
SoapProcessor(HelloWorld obj) {
instance = obj;
}
@Override
public void process(Exchange exchange) throws Exception {
System.out.println("Start Process...");
String inputText = exchange.getIn().getBody(String.class);
String response = instance.sayHi(inputText);
exchange.getMessage().setBody(response);
System.out.println("End Process...");
}
}
本クラスの中で、サービス実装クラス HelloWorldImplを呼び出す。
Mainを実装する
package example;
import org.apache.camel.CamelContext;
import org.apache.camel.impl.DefaultCamelContext;
public class Main {
public static void main(String[] args) throws Exception {
System.out.println("Server ready...");
try (CamelContext context = new DefaultCamelContext()) {
context.addRoutes(new SoapRouteBuilder(new SoapProcessor(new HelloWorldImpl())));
context.start();
System.out.println("Sleep...");
// コンソールで実行した時にすぐ終了するため、スリープを入れる
Thread.sleep(5 * 60 * 1000);
}
System.out.println("Server exiting");
}
}
動作確認
エンドポイントへの接続確認 兼 WSDLファイルを取得
コンソールアプリケーションを起動後に、Webブラウザに以下URLを入力する。
http://localhost:9006/soap?wsdl
以下のようにWSDLが表示されたら、接続確認はOK。ブラウザ表示内容をWSDL形式で名前を付けて、保存する。
SoapUIからSOAPメッセージを送信する
前の手順で取得したWSDLファイルを取り込み、SoapUIからSOAPメッセージを送信する。
画面の左側が、送信元の情報(要求パラメータを設定する画面)である。
画面の右側が、実行結果(Raw形式表示)である。
実行結果がHTTPステータス 200となっており、SOAP通信に成功したことを確認した。
実行結果をXML形式表示に切り替えて、応答情報が期待通りかを確認する。
応答情報のタグに、期待通りの文字列(※)が格納されていることを確認した。
※サービス実装クラス HelloWorldImplの戻り値
ソースコードの格納場所
参考サイト
No | リンク | 備考 |
---|---|---|
1 | Camel-Core>Working with Camel Core | Apache Camel Coreの機能全体を俯瞰するときに、利用した。 |
2 | 10分で基礎をマスターするApache Camel | Apache Camelの使い方をわかりやすく解説しているQiitaの記事。 |
3 | Apache Camelの公式サンプル | Apache Camelの公式サンプル。 |
4 | Camel>Components>CXF | Apache CamelのCXFコンポーネントに関するページ。 |
5 | Apache CXF>A simple JAX-WS service | Apache CXFのみでSOAP通信を行うクライアント、サーバーの実装例として参考にした。 |
6 | Apache CXF>JAX-WS Developing a Service#JavaFirstDevelopment | Apache CXFでJAX-WSを使用したサービス開発の方法がまとめられたページ。 |
7 | Apache CXF>Example Projects | Apache CXFのサンプルプロジェクトの一覧。 |
8 | Apache CXF>Maven POM Information | Apache CXFの依存関係に関する説明。 |
9 | examples>camel-example-cxf | camel-2.19.5版におけるCamel CXF のサンプル。GitHubからクローンしたが、ビルドに失敗した。camel-2.19.5版のサンプルの実装を、本記事の実装の参考にした。 |
10 | Apache Maven>POM Reference | POMのリファレンス |
11 | Apache Camel CXF Example | Apache Camel&Apache CXF& Springを組み合わせたサンプル。 |
12 | SOAP Webservices using Apache Camel, Springboot and CXF | Apache Camel&Apache CXF& Springbootを組み合わせたサンプル。 |
13 | CXF example : SOAP(JAX-WS), REST(JAX-RS), Spring | Apache Camel&Apache CXF& Springを組み合わせたサンプル。 |
14 | camel-spring-boot-examples>soap-cxf | Apache Camel&Apache CXF& Springbootを組み合わせたサンプル。 |