SAStruts JSONを返すアクションメソッド 修正編

SAStruts アクションにJSONを返すメソッドを作成してみる - 130単位

↑で書いたコードに対し、気になった点があって直そうと思いました。が、あまりに修正点が多かったので新たに記事にしてみます。

以前のコード

Ajaxでリクエストされ、従業員のリストをJSON形式で返すメソッドです。

@Execute(validator = false)
public String ajaxEmployeeList() {
    List<Employee> employeeList = employeeService.findByDeptId(form.departmentId);
    
    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;
}

修正4点

Mapの順序を固定する

HashMapだと、値の順序が保証されません。実際にJSON文字列ではバラバラになってしまっていて、受け側のJavaScriptで扱う際にも影響が出ていました。

HashMap<String, String> map = new HashMap<String, String>();

LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();

これで、putした順序通りにJSONに変換されます。ただし期待する結果を得るためには、employeeService#findByDeptId()での照会の際にOrderBy()を利用してソートしておくことが必要です。

また、Mapにはキーの値で自動的にソートされるTreeMapという実装もあるようです。こちらなら、OrderBy()しておく必要はなさそうです。パフォーマンスも含めてどちらが適しているかは未調査です…。

インタフェース型で宣言する

変数などの宣言には、インタフェースを用いるのが良いようです。

LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();

Map<String, String> map = new LinkedHashMap<String, String>();

大きな理由としては、コードに柔軟性を持たせるためだと認識しています。『Effective Java』が詳しいです*1

JSONICを使う

前の記事でも触れましたが、JSONSerializerは@deprecatedとなっているため、JSONICを利用します。

JSONSerializer.serialize(map)

//import net.arnx.jsonic.JSON; が必要
JSON.encode(map)
Content-Typeを「application/json」にする

RFCで定められているように、"application/json"を使うことにします。

修正したコード

以上4点を修正したコードです。

@Execute(validator = false)
public String ajaxEmployeeList() {
    List<Employee> employeeList = employeeService.findByDeptId(form.departmentId);
    
    Map<String, String> map = new LinkedHashMap<String, String>();
    for (Employee emp: employeeList) {
        map.put(emp.id, emp.name);
    }
    
    ResponseUtil.write(JSON.encode(map), "application/json");
    return null;
}

ついでに

これまでの記事で、「デパート」→「部署」に変えておきした。常識的な英語表現っぽくてなんとなく恥ずかしかったので。

原文地址:https://www.cnblogs.com/aggavara/p/2708755.html