[java][ruby] JRubyからJavaのHttpClientを使う
今日、railsで作ってるサーバへの疎通確認をしてもらってたんですが、サーバとクライアントのどちらに問題があるのかわからなかったので、問題を切り分けるためにクライアント側で使うライブラリでちゃんとアクセスできるかどうか確認することにしました。
クライアントはJavaのhttpclientを使っているので、僕としては当然JRubyで使うわけです。書いたコードはこんな感じです。
localhostに対してGET /foo.json で得られたbarを POST /bazのパラメータとして使って送信してます
# -*- coding: utf-8 -*- require 'java' require 'rubygems' require 'json' # カレントディレクトリのlib以下に使用するjarを置いてください。 # jarは http://hc.apache.org/downloads.cgi のBinary とかからゲット可能です。 Dir['./lib/*.jar'].each{|f| require f} import "java.io.BufferedReader" import "java.io.InputStreamReader" import "java.net.URLEncoder" import "java.util.ArrayList" import "org.apache.http.client.entity.UrlEncodedFormEntity" import "org.apache.http.client.methods.HttpPost" import "org.apache.http.client.methods.HttpGet" import "org.apache.http.entity.StringEntity" import "org.apache.http.impl.client.DefaultHttpClient" import "org.apache.http.message.BasicNameValuePair" import "org.apache.http.protocol.HTTP" client = DefaultHttpClient.new req = HttpGet.new("http://localhost/foo.json") res = client.execute(req) puts "status_code: #{res.getStatusLine.toString}" rd = BufferedReader.new(InputStreamReader.new(res.getEntity.getContent)) lines = [] while line = rd.readLine lines << line end res_obj = JSON.parse(lines.join) # このJSONのparseはRubyのgemである"json"を使って行っています。 bar = res_obj['bar'] # GET /foo.json で得られたbarを POST /bazのパラメータとして使う req = HttpPost.new("http://localhost/baz") values = ArrayList.new(1) values.add(BasicNameValuePair.new("bar", bar)) req.setEntity(UrlEncodedFormEntity.new(values, HTTP::UTF_8)) res = client.execute(req) puts "status_code: #{res.getStatusLine.toString}" rd = BufferedReader.new(InputStreamReader.new(res.getEntity.getContent)) while line = rd.readLine puts line end
難しいRubyの文法を使わなかったのでJavaでクライアント側の実装をやってる人に読んでもらえたのが良かったです。
でも通信自身とは関係ない部分で、さりげなくJSON.parseとかRubyのライブラリを組み合わせて使っています。
rvmさえインストールされていれば、
$ rvm install jruby $ rvm jruby $ gem install json
で上記に必要なインストールは完了するはず。
あとは上のファイルの名前を java_httpclient_example.rb とするなら
$ jruby -S java_httpclient_example.rb
とかで実行できちゃいます。コンパイル不要です。
ちょっとだけJavaのライブラリを触るときにはこんな感じでやれると楽だなーと久しぶりに実感しました。