MessagePackに触れてみる

こないだの週末にMessagePackのオンラインハッカソンがあったってのは知ってたのですが、 MessagePackは自分にとっては、使ってるミドルウエアに内包されてるくらいで、 特にソレそのものをホゲホゲするあれでもなく、、。@muga_nishizawaがやってるって事で触ってみよかなー、と。   ■ やること   1. JavaでHTTPクライアント作ってMessagePackでシリアライズしたデータを送信 2. Java(Spark)でサーバーを立てて取得したデータをMessagePackでデシリアライズ 3. Ruby(Sinatra)でサーバーを立てて取得したデータをMessagePackでデシリアライズ   1.と2.はIntelliJ IDEAで、3.はRubyMineでやっていきます。 #言語間をまたぐってのはアレなのですが、先日IntelliJに関するブログを書きましたが、 #実はその時のJetBrainsの75%オフセールでRubyMineのライセンスも買いました。 #どうも調べてくと、IntelliJとRubyMineは同じコードベースで、IntelliJにはRubyMineのプラグインが #あるっちゅうことで、RubyMineのライセンス要らなかったじゃんって感じなのですが、 #せっかく買ったので使ってみたいなと…w   JavaでHTTPクライアント   application/octet-streamでMessagePackでシリアライズしたHogeオブジェクトを bodyに詰めてサーバーに送信します。 #後からみたらコンテントタイプはapplication/x-msgpackが良さげですかね~

public class MessagePackHttpClient {
    public static void main(String args[]) throws Exception{
        Hoge hoge = new Hoge();
        hoge.id = 1;
        hoge.message = "Hello Hoge!";

        DefaultHttpClient client = new DefaultHttpClient();
        HttpHost host = new HttpHost("localhost", 【ポート】);
        HttpPost post = new HttpPost("/");

        MessagePack messagePack = new MessagePack();
        ByteArrayEntity entity = new ByteArrayEntity(messagePack.write(hoge), ContentType.create("application/octet-stream"));
        post.setEntity(entity);

        HttpResponse response = client.execute(host, post);
        System.out.println(response.getStatusLine().getStatusCode());
        client.getConnectionManager().shutdown();
    }
}

ちなみにHogeオブジェクトは↓こんな感じ。@Messageアノテーション付ける。お手軽。

@Message
public class Hoge {
    public int id;
    public String message;
}

HTTPクライアント、MessagePack、Spark(サーバー用)をpom.xmlに定義。

<repositories>
    <repository>
        <id>Spark repository</id>
        <url>http://www.sparkjava.com/nexus/content/repositories/spark/
    </repository>
</repositories>
<dependencies>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.2.3</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.msgpack</groupId>
        <artifactId>msgpack</artifactId>
        <version>0.6.7</version>
    </dependency>
    <dependency>
        <groupId>spark</groupId>
        <artifactId>spark</artifactId>
        <version>0.9.9.4-SNAPSHOT</version>
    </dependency>
</dependencies>

    Java(Spark)でサーバーを立てて取得したデータをMessagePackでデシリアライズ   POSTで取得したbodyのバイト配列を取得するのにHttpServletRequestで~ってやんなきゃなのは ちょっとめんどくちゃいなぁ。

public class SparkSample {
    public static void main(String[] args) {
        setPort(9996);
        post(new Route("/") {
            @Override
            public Object handle(Request request, Response response) {
                MessagePack messagePack = new MessagePack();
                try {
                    System.out.println(request.body());
                    HttpServletRequest req = request.raw();
                    Hoge hoge = messagePack.read(req.getInputStream(), Hoge.class);
                    System.out.println("id:" + hoge.id);
                    System.out.println("message:" + hoge.message);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return "Hello";
            }
        });
    }
}

    Ruby(Sinatra)でサーバーを立てて取得したデータをMessagePackでデシリアライズ   なんでしょうね、このお手軽さ。。 ただ、Javaクライアントの@Messageでシリアライズしたデータが、Rubyの中でどう解釈されてるのか 調べたいなぁ。RubyのクライアントからJavaに送るときにreadでオブジェクトにセット出来なかったりしたので。

class SinatraSample
  require 'sinatra'
  require 'msgpack'
  set :port, 9997
  post '/' do
    puts MessagePack.unpack(request.body.read)
  end
end

    ■ そんなこんなで、、   JSONで他システムとデータをやりとりする機会がココ数年すごい増えてるので、 言語をまたいでサクっと扱えるこのライブラリはナイスだな~。   あと、JetBrainsのプロダクト使ってくと、あんまりJavaが苦じゃない事が多いかも。 もちろんRubyMineもGemのインストールとかスゴイ楽チンだし、Sinatraを使った時の コードの短さとかもビビりますけどね。。   そういえばDeNAさんの↓この本にもMessagePackの記載あったような。また読み返そうかな。