部署: 従業員:
このような2つのセレクトボックスがあって、部署の選択に応じて、従業員のセレクトボックスを動的に生成したいとします。
これを、Ajaxを使ってSAStrutsで実現しようとしてました。
StringBufferの例
アクションにAjaxリクエスト用のメソッドを作成します。
※ パラメータの部署idはアクションフォームで定義されているとします。
@Execute(validator = false) public String ajaxEmployeeList() { List<Employee> employeeList = employeeService.findByDeptId(form.depertmentId); StringBuilder buf = new StringBuilder(100); buf.append("{"); for (Employee emp: employeeList) { buf.append("\""); buf.append(emp.id); buf.append("\":\""); buf.append(emp.name); buf.append("\","); } buf.setLength(buf.length() - 1); buf.append("}"); ResponseUtil.write(buf.toString(), "text/javascript"); return null; }
idとnameさえ得られれば良いので、単純にStringBufferで書いてみました。最後にユーティリティクラスのResponseUtilを使ってJSONを出力しています。ちなみに、最初はgetEmployeeList()という名前にしようとしたのですが、Getterと解釈されるっぽいので違う名前にしました。
ただ、やはりどうもコードにすっきり感がありません。
で、なんとなく「json」と書いてコード補完をしてみたら、「JSONSerializer」なるクラスを発見。serialize()というメソッドがあり、どうやらこれで出来そうです。
JSONSerializerの例
追記:修正した記事↓を書きました。なお、JSONSerializerは非奨励とされています。
SAStruts JSONを返すアクションメソッド 修正編 - 130単位
※ org.seasar.framework.util.JSONSerializerをインポートします。
@Execute(validator = false) public String ajaxEmployeeList() { List<Employee> employeeList = employeeService.findByDeptId(form.depertmentId); HashMap<String, String> map = new HashMap<String, String>(); for (Employee emp: employeeList) { map.put(emp.id, emp.name); } ResponseUtil.write(JSONSerializer.serialize(map), "text/javascript"); return null; }
コードを短くするなら、エンティティのListをそのままJSONに変換してもいいと思います。その際エンティティに導出プロパティがあった場合、正しく定義していないと例外が発生してしまうので注意が必要です。
Content-Type
ResponseUtil#write()の第二引数にContent-Typeを指定していますが、JSONは"application/json"とするのが本来は正しいようです。
JSONのContent-Typeは application/json(管理人日記) - むぅもぉ.jp http://muumoo.jp/news/2006/09/26/0applicationjson.html
ちなみに第二引数なしだと"text/plain"になります。"application/json"と"text/javascript"と"text/plain"、それぞれのContent-Typeを各ブラウザで試してみましたが、IE6/Firefox3/Safari/Chromeどれでも問題ありませんでした。
ところが
記事を書くにあたってリンクを張ろうとしてみたら、以下のような記述が。
推奨されていません。 このクラスの代わりにJSONIC等を使用してください
JSONSerializer (Seasar2 Framework 2.4.46 API)
JSONからの変換の際に、うまくいかないケースがあるようです。
[#CONTAINER-339] [S2Container] JSONSerializer を deprecated にしました.代わりに JSONIC 等を使用してください. - The Seasar Foundation Issues https://www.seasar.org/issues/browse/CONTAINER-339
参考リンク
というわけで、JSONICを使うように修正したいと思います。以下参考記事。
suz-lab - blog: S2JDBC - SAStruts - JSON - jQuery http://suz-lab.blogspot.com/2008/09/s2jdbc-sastruts-json-jquery.html SAStruts + JSONIC でバリデーションエラーをJSONで返す : json, sastruts, seasar | メモリークラフト http://www.memorycraft.jp/2008/11/sastruts-jsonic-json.html