Google App EngineにRESTなサービスを追加したいと思います。
RESTなリクエストをパラメータとして解析するサーブレットとしてJSONICの
net.arnx.jsonic.web.RESTServlet
を使用してみました。これはweb.xmlの設定で
"mappings": { "/{class}/{source}.json":"nu.mine.kino.gae.controller.Ajax${class}Controller" }
とか書くことで、
/hoge/fuga.json
へのリクエストを、
nu.mine.kino.gae.controller.AjaxHogeController#find(Map params)
へ転送することができたり、戻り値のオブジェクトを自動でJSON形式に変換してくれたりする便利なサーブレットです。ちなみに上記の例だとparamsからは params.get("source")とやってパラメタの値(この例だとfuga)を取得することが出来ます。
実際簡単なプログラムでやってみます。RESTのURIとして
/text2unicode/t/[文字(をURL Encodeしたもの)].json
を呼び出すと、
{ "text":"文字", "unicode":"文字をUnicode表記したもの" }
を返すようなものを考えます。
たとえば、
/text2unicode/t/%E3%81%82.json <-「あ」をURL Encodeしたもの
にアクセスすると、
{"text":"あ","unicode":"\\u3042"}
が返却されるようにします。
JSONICのインストールは簡単で、JSONIC - simple json encoder/decoder for java からダウンロードしてきてjarをWEB-INF/libにおくことと、web.xmlに以下を追加します。
<servlet> <servlet-name>restServlet</servlet-name> <servlet-class>net.arnx.jsonic.web.RESTServlet</servlet-class> <init-param> <param-name>config</param-name> <param-value> { "debug": true, "mappings": { "/{class}/{uort}/{source}.json":"nu.mine.kino.gae.rest.Ajax${class}Controller" } } </param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>restServlet</servlet-name> <url-pattern>*.json</url-pattern> </servlet-mapping>
マッピングを
"/{class}/{uort}/{source}.json":"nu.mine.kino.gae.rest.Ajax${class}Controller"
このようにしたので
/text2unicode/t/%E3%81%82.json
にアクセスすると、
nu.mine.kino.gae.rest.AjaxText2unicodeController#find(Map params)
が呼び出され、パラメタに
{source=%E3%81%82, class=text2unicode, uort=t}
というMapが渡されてきます。
戻りのオブジェクトは下記のようなPOJOを定義します。ちなみのこのPOJOは上記のfindメソッドの戻り値にしますが、JSONICはPOJOなオブジェクトを自動でJSON形式に変換してくれます。
public class UnicodeTextObject { private String text; private String unicode; ...Getter/Setter省略 }
nu.mine.kino.gae.rest.AjaxText2unicodeControllerを実装します。こんな感じです。
public class AjaxText2unicodeController { public UnicodeTextObject find(Map<String, String> params) throws UnsupportedEncodingException { String source = URLDecoder.decode(params.get("source"), "UTF-8"); String uort = params.get("uort"); System.out.println(params); UnicodeTextObject create = new TextUtilsService().create(source, uort.charAt(0)); return create; } }
public class TextUtilsService { public String unicode2Text(String unicode) { return StringEscapeUtils.unescapeJava(unicode); } public String text2Unicode(String text) { return StringEscapeUtils.escapeJava(text); } public UnicodeTextObject create(String source, char c) { UnicodeTextObject ret = new UnicodeTextObject(); switch (c) { case 'u': //urlがuなら unicode -> text String unicode2Text = unicode2Text(source); ret.setText(unicode2Text); ret.setUnicode(source); break; case 't': //urlがtなら text -> unicode String text2Unicode = text2Unicode(source); ret.setUnicode(text2Unicode); ret.setText(source); break; default: ret.setText(source); ret.setUnicode(source); break; } return ret; } }
いろいろ書いてますが、
public UnicodeTextObject find(Map<String, String> params);
このメソッド内で
String source = URLDecoder.decode(params.get("source"), "UTF-8");
このように引数のMapからパラメタを取得し、
UnicodeTextObject create = new TextUtilsService().create(source, uort.charAt(0)); return create;
としてPOJOを作成して返しているだけですね。
ちなみにこのメソッド
public UnicodeTextObject find(Map<String, String> params)
このシグネチャは、WebサービスAPI (JSONIC 1.3) の規約に則って、クライアントからのリクエストにマッピングされるようです。インタフェースとかがない緩い感じの規約です。
あ書き忘れましたが、Unicode表記の文字列を取得するのに
StringEscapeUtils.escapeJava(text);
とCommons Langを使ってるのでそのjarもWEB-INF/libに入れとく必要がありますね。
試しにGoogle App Engineを起動して
http://localhost:8888/text2unicode/t/%E7%B0%A1%E5%8D%98%E3%81%ABREST%E3%81%A7%E3%81%8D%E3%81%9F.json
へブラウザとかREST ClientとかでGetでアクセスしてみましょう。
{"text":"簡単にRESTできた","unicode":"\\u7C21\\u5358\\u306BREST\\u3067\\u304D\\u305F"}
が返却されました!
この記事は
現在のアクセス:4187