struts2でJSONを出力する

struts2でJSONを結果として出力したいとなったときのために、JSON Pluginがあります。

これとconvention pluginのアノテーションを使って実際に試してみました。

もちろんJSONとなる文字列を作って、InputStreamオブジェクトに設定してStream Resultとして返してもいいんですが、折角あるものを使わない手はないし何よりめんどくさいので、そんなことはしません。

Mavenに追加

まずはpom.xmlにpluginを追加します。

   <dependency>
       <groupId>org.apache.struts</groupId>
       <artifactId>struts2-json-plugin</artifactId>
       <version>STRUTS_VERSION</version>
   </dependency>

このjarファイルにあるstruts-plugin.xmlにresult type=jsonが定義されています。

ここではidとnameプロパティを持つオブジェクトのリストをあらわすJSONを返します。

Action
package kamegu.action.fwtest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Results;

import com.opensymphony.xwork2.Action;

@Results({
	@org.apache.struts2.convention.annotation.Result(name="success", type="json", params={"root", "list"})
})
@ParentPackage("json-default")
public class JsonAction implements Action {

	public List<Map<String, Object>> list = new ArrayList<>();
	@Override
	public String execute() throws Exception {
		list.add(createCustomer(10l));
		list.add(createCustomer(11l));
		list.add(createCustomer(12l));
		return SUCCESS;
	}

	private Map<String, Object> createCustomer(long id) {
		Map<String, Object> customer = new HashMap<>();
		customer.put("id", id);
		customer.put("name", "name" + id);
		return customer;
	}
}

クラスにアノテーションを2つ設定しています。

以上で対応するURLにアクセスしてみると、次のようなレスポンスが返ってくるかと思います。

[{"id":10,"name":"name10"},{"id":11,"name":"name11"},{"id":12,"name":"name12"}]
JSON resultの説明
  • デフォルトだとアクションクラスをJSON化します。rootパラメータを設定すればその名前のフィールドをJSON化します。
  • JSON化されるのはJavaBean出ないとダメっぽい(getter/setter)参考

詳しくはJSON pluginのページみてください

アノテーションを使わないような書き方

アノテーションを使わずにjson resultを使います。
struts2でresultの設定をxmlにもアノテーションにも指定しない方法を使います。

Action
package kamegu.action.fwtest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.struts2.json.JSONResult;

import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.Result;

public class JsonAction implements Action {

	public List<Map<String, Object>> list = new ArrayList<>();
	@Override
	public String execute() throws Exception {
		return SUCCESS;
	}

	public Result test() {
		list = new ArrayList<>();
		list.add(createCustomer(1l));
		list.add(createCustomer(2l));
		list.add(createCustomer(3l));
		JSONResult result = new JSONResult();
		result.setRoot("list");
		return result;
	}

	private Map<String, Object> createCustomer(long id) {
		Map<String, Object> customer = new HashMap<>();
		customer.put("id", id);
		customer.put("name", "name" + id);
		return customer;
	}
}

これ、結構使える気がします。