こないだの週末に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の記載あったような。また読み返そうかな。