LoginSignup
20
20

More than 5 years have passed since last update.

処理に合わせて自動的にデータを変換する (Apache Camel)

Last updated at Posted at 2016-01-31

Apache Camelでの実装イメージ

スクリーンショット 2016-01-31 9.06.51.png

この"処理"を実装する

  • 処理は分担して実装できる
  • 処理は何かのメッセージを受けて、何かのメッセージを返すだけ。
  • 前の処理や後の処理の依存度が低ければ、処理の入れ替えや修正が簡単になる。

メッセージの形式

メッセージには下記の情報が含まれている。
処理はこの情報にデータ出し入れするだけ。

  • Header (Map)
  • Property (Map)
  • Body (Object)
  • Attachement

処理

処理の中では前の処理を考えずに、どういう型が欲しいかを書いてデータを取得する。
単なるキャストだけではなく、データ変換も行える

例えば、BodyからString形式で情報を取得したい場合は下記のように書く。

String body = exchange.getIn().getBody(String.class);

この時、メッセージの内容がIntegerでもFloatでもFileでもxmlでもInputStreamでも、Camelが自動的に変換してString形式にしてくれる。
(変換できなかったら type converterが見つかりませんみたいなエラーが出る。)

Headerの場合は

String header = exchange.getIn().getHeader("headerName", String.class);

この仕組を使って

from("file:test")
.to("http:xxxxxx");

と実装すると、フォルダを監視して、ファイルを発見するとFileインスタンスでメッセージを流して、そのあとhttpでファイルの内容を送信する事ができる

この例では、
* ファイル処理の実装は「ファイルを読み込んでメッセージに詰め込む」だけで、後の処理に何が入るかを考えていない。
* http送信処理の実装は「メッセージを読み込んで内容を送信する」だけで、手前の処理がファイル処理だろうが、FTP処理だろうかは考えていない。

独自のデータ変換登録

前の例ではCamelがデフォルトで持っているデータ変換処理を使ってデータを変換しているが、デフォルトで実装しているデータ変換で間に合わない場合はもちろんエラーになる。

たとえば、Mapをbyte[ ]に変換する場合は一律Json形式にすると決めたら下記のクラスを置いておけばいいだけ。
これで、この変換が必要な場合にCamelが呼び出す。

import com.fasterxml.jackson.core.JsonProcessingException;
import org.apache.camel.Converter;

import java.io.UnsupportedEncodingException;
import java.util.Map;

@Converter
public class MapConverter {

    @Converter
    public static byte[] toByteArray(Map map) throws JsonProcessingException, UnsupportedEncodingException {
        ObjectMapper objectMapper = new ObjectMapper();
        String json = objectMapper.writeValueAsString(data);
        return json.getBytes("utf-8");
    }

}

@Converterに関して、どこに置いても反応してくれるかどうかはドキュメントに書いてあるのかも。。。
私は同一プロジェクトの別パッケージ内にクラスを置いたけど動作していた。

参考
http://camel.apache.org/type-converter.html

このクラスを置いておくだけで、下の例のようなMapをhttpで送信する時には自動的にjsonに変換して送信してくれる

例:

.......
.process(exchange -> {
    Map map = new HashMap();
    map.put("aaa", 111);
    map.put("bbb", 222);
    exchange.getIn().setBody(map);
})
.to("http:....")

明示的に型変換をする場合

from("file:xxx")
.convertBodyTo(String.class)

だったり

from("file:xxx")
.process(exchange -> {
    String body = exchange.getIn().getBody(String.class);
    exchange.getIn().setBody(body);
})

javaオブジェクト --> json

from("xxxxxxxx")
.marshal().json(JsonLibrary.Jackson)
.to("yyyyy")

json --> javaオブジェクト

from("xxxxxxxx")
.unmarshal().json(JsonLibrary.Jackson)
.to("yyyyy")
20
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
20