MessageConverterを利用したメッセージの変換
先ほどメッセージを送受信した際に利用したメソッド名に「convert」とありました。 Spring AMQPでは、MessageConverterという仕組みを利用して、メッセージの送受信時にオブジェクトからメッセージへの変換とその逆であるメッセージからオブジェクトへの変換を行う仕組みが備えられています。標準ではSimpleMessageConverterというコンバータが適用されています。これはその名のとおりシンプルにメッセージとオブジェクトをテキストベースで変換します。
今回はこのSimpleMessageConverterではなくオブジェクトとメッセージをJSON形式で変換してみます。JSON形式での変換を行うためにJsonMessageConverterというものが用意されています。
以下のようなシンプルなクラスを用意してください。これ自体は何の変哲もないクラスです。
public class SimplePojo {
private String key;
private String message;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
次に先ほどのSenderクラスを少し変更し、このクラスを利用して作成したオブジェクトに値をセットしてメッセージを送信します。この時点ではデフォルトのSimpleMessageConverterが使われるため、メッセージを送信しても何も行われないどころかテキストへの変換も行われません。
そこでSimpleMessageConverterの代わりに、JsonMessageConverterを利用するように設定を行います。この設定は、SampleConfigクラスで定義したRabbitTemplateクラスにJsonMessageConverterをインスタンス化したものをセットすることで行います。
@Bean
public RabbitTemplate rabbitTemplate() {
RabbitTemplate template = new RabbitTemplate(connectionFactory());
template.setRoutingKey("sample_queue");
template.setQueue("sample_queue");
template.setMessageConverter(new JsonMessageConverter());
return template;
}
]
このJsonMessageConverterはJavaでJSONを扱うためのライブラリである「Jackson Java JSON-processor」を必要とします。従って依存関係として、以下の記述をpom.xmlに追加します。
<dependencies>
(中略)
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.2</version>
<scope>compile</scope>
</dependency>
</dependencies>
そしてSenderでメッセージを送る箇所を、オブジェクトを利用して送るように変更します。
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Sender {
public static void main(String[] args){
ApplicationContext context = new AnnotationConfigApplicationContext(SampleConfig.class);
AmqpTemplate amqpTemplate = context.getBean(RabbitTemplate.class);
SimplePojo simplePojo = new SimplePojo();
simplePojo.setKey("ABC");
simplePojo.setMessage("This is message made by pojo.");
amqpTemplate.convertAndSend(simplePojo);
System.out.println("Sent message.");
}
}
先ほど作成したSimplePojoをインスタンス化して、keyとmessageをセットしたオブジェクトをそのままconvertAndSendメソッドに渡します。修正したSenderクラスを実行してみてください。
実際にどのようにメッセージが送られているか分かりやすく確認するため、ここでは先程作成したReceiverクラスではなくRabbitMQのWeb管理画面で確認してみます。ブラウザでhttp://localhost:55672/にアクセスしてください。
上部に並んでいるタブから「Queue」をクリックしてください。今回のアプリケーションで利用している「sample_queue」という名前のキューが作成されていることが分かります。また、sample_queueのMasseges列のready列が1となっているかと思われます。
表中に「sample_queue」という文字列がありますので、そちらをクリックします。すると「sample_queue」の画面に移りますので、ページ中程のGet messagesというセクションを探してください。このセクションにある「Get Message(s)」ボタンをクリックすると、メッセージのプロパティなどと共にメッセージの内容がPayloadとして表示されます。先ほどオブジェクトに値をセットして送信したメッセージがJSON形式になっていることが確認できると思います。
続いてReceiver側も変更します。
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Receiver {
public static void main(String[] args){
ApplicationContext context = new AnnotationConfigApplicationContext(SampleConfig.class);
AmqpTemplate amqpTemplate = context.getBean(RabbitTemplate.class);
SimplePojo simplePojo = (SimplePojo)amqpTemplate.receiveAndConvert();
System.out.println("Receive message: key = " + simplePojo.getKey() + ", message = " + simplePojo.getMessage());
}
}
Receiverでは、reciveAndConverメソッドの結果をキャストして受け取ります。すると、JSON形式となっているメッセージ内容がオブジェクトへとマッピングされていますのでgetterメソッドを用いてフィールドの値を取得します。
JsonMessageConverterによる変換は、デフォルトではDefaultClassMapperを利用して行われます。DefaultClassMapperはメッセージのプロパティに含まれる情報を元に変換先となる型を特定してマッピングを行います。
まとめ
今回はSpring AMQPを利用したアプリケーションの第一歩として、RabbitMQの導入から実際にSpring AMQPを利用した簡単なメッセージ送受信までを行なってみました。
今回の例では解説を行いませんでしたが、Spring AMQPはSpring Frameworkがベースとなっているため、DI等の仕組みも利用できます。@Autowiredによるインジェクションを利用するとMQへの接続部分などは個々の処理クラスには記述する必要がなく、メッセージのやり取りを簡略化できます。
次回はSpring AMQPを利用してのリスナーの実装と、RabbitMQを冗長化した場合のアプリケーション側の対応について解説したいと思います。



