読者です 読者をやめる 読者になる 読者になる

Slim3でjson/jsonpレスポンスを返すJsonController

GAE/J

 以前使ったものをJsonControllerとして作成してみました。動作確認用です。

JsonController.java

package mcclabs.controller;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

import net.arnx.jsonic.JSON;

import org.slim3.controller.Controller;
import org.slim3.util.ThrowableUtil;

/**
 * JSON/JSONPレスポンスを返すメソッドを持つController.
 * 
 * @author Kenichiro Murata
 */
public abstract class JsonController extends Controller {

    /**
     * JSON/JSONPレスポンスを返すメソッド.
     * runから呼び出した後、runメソッドではnullをreturnする.
     * 
     * @param data
     */
    protected void toJson(Object data) {
        // エンコーディングを取得する
        String encoding = request.getCharacterEncoding();
        if (encoding == null) {
            encoding = "UTF-8";
        }

        // JSON形式にエンコード
        String script = JSON.encode(data);
        // コールバックメソッドの指定がある場合はJSONP形式に変換する
        String callback = param("callback");
        if (callback != null) {
            final StringBuilder builder =
                new StringBuilder(script.length() + callback.length() + 10);
            builder.append(callback);
            builder.append("(");
            builder.append(script);
            builder.append(");");
            script = builder.toString();
        }

        // ContentTypeを設定する。
        final StringBuilder builder = new StringBuilder(38);
        builder.append("application/");
        if (callback != null) {
            builder.append("javascript");
        } else {
            builder.append("json");
        }
        builder.append("; charset=");
        builder.append(encoding);
        response.setContentType(builder.toString());

        // レスポンスに書き込む
        try {
            PrintWriter out = null;
            try {
                out =
                    new PrintWriter(new OutputStreamWriter(response
                        .getOutputStream(), encoding));
                out.print(script);
            } finally {
                if (out != null) {
                    out.close();
                }
            }
        } catch (IOException e) {
            ThrowableUtil.wrapAndThrow(e);
        }
    }
}

 オブジェクトのJSON.encodeにはJSONICを使っています。

HelloController.java(利用側)

package mcclabs.controller.twitter;

import java.util.HashMap;
import java.util.Map;

import mcclabs.controller.JsonController;

import org.slim3.controller.Navigation;

public class HelloController extends JsonController {

    @Override
    public Navigation run() {
        Map<String, String> data = new HashMap<String, String>();
        data.put("FirstName", "Kenichiro");
        data.put("LastName", "Murata");

        this.toJson(data);

        return null;
    }
}

追記
一部修正しました。