SAStruts で JSONデータをFORMに入れる

前略、ここに記載のソースは動作を保証するものでは無い…orz


少し前(数年)から、Seasar2 にお世話になってます。

毎回「SASturts だったら、何もしなくてもJSONデータをFORMに入れてくれるだろっ!」って放置していると、JSONデータがサーバーで取得出来ねぇ~~~~~~って嘆きます。そして毎回調べる…(鳥頭)


で、JSONICライブラリーを設定後、やることは、ほぼココと同じです。
http://qiita.com/shiena/items/146a0504c026ba00fbd0
(ココってトラックバックが無い…ダメならリンクをすぐに消します To shiena様)

元ソースは「Jackson」でJSONデータを分解しています。
下記ソースは「JSONIC」でJSONデータを分解しています。(あと私はfinalを付けたい人です)
****************ここから*********************
package sample.custom.common;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.arnx.jsonic.JSON;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.seasar.framework.beans.util.Beans;
import org.seasar.framework.util.ReaderUtil;
import org.seasar.struts.action.S2RequestProcessor;
import org.seasar.struts.util.S2ActionMappingUtil;

public class S2JSONRequestProcessor extends S2RequestProcessor {

    /**
     * {@inheritDoc}
     */
    @Override
    protected void processPopulate(final HttpServletRequest request,
                                   final HttpServletResponse response,
                                   final ActionForm form,
                                   final ActionMapping mapping) throws ServletException {

        if (form == null) {
            return;
        }

        final String contentType = request.getContentType();
        final String method = request.getMethod();

        if (contentType != null &&
                contentType.startsWith("application/json") &&
                "POST".equalsIgnoreCase(method)) {

            form.setServlet(servlet);
            form.setMultipartRequestHandler(null);
            processExecuteConfig(request, response, mapping);
            form.reset(mapping, request);

            final Object actionForm = S2ActionMappingUtil.getActionMapping().getActionForm();

            try {
                // JSONICでpurseする
                final String postBody = ReaderUtil.readText(request.getReader());
                final Object value = JSON.decode(postBody, actionForm.getClass());

                Beans.copy(value, actionForm).execute();

            } catch (final IOException e) {

                log.error(e.getMessage(), e);
                throw new ServletException(e.getMessage(), e);
            }
        } else {

            super.processPopulate(request, response, form, mapping);
        }
    }
}

****************ここまで*********************


で、struts-config.xml ファイルの下記の場所を修正
****************ここから*********************


    <controller
        maxFileSize="1024K"
        bufferSize="1024"
        processorClass="sample.custom.common.S2JSONRequestProcessor"
        multipartClass="org.seasar.struts.upload.S2MultipartRequestHandler"/>

****************ここまで*********************




Extjs でデータを送るのはこんな感じ:
(params では無く、jsonData でパラメータを設定する)
****************ここから*********************
Ext.Ajax.request({
    url      : url,
    method   : 'POST',
    jsonData : {
        type : 1,
        title: {
            id    : e.record.data.id,
            name  : e.newValues.name,
            kikan : e.newValues.kikan,
            ext   : e.newValues.ext,
            test  : ['aiueo', 'kakikukeko'],
            others : {
                    no: 10,
                    name: 'あいうえお'
            }
        }
    },
    scope    : me,
    callback : me.callBackRequest
});

****************ここまで*********************


実際に送られるデータはこんな感じ:(fire bugs より)
****************ここから*********************
{"type":1,"title":{"id":"1234567890","name":"asdf","kikan":"asdf","ext":"asdf","test":["aiueo","kakikukeko"],"others":{"no":10,"name":"\u3042\u3044\u3046\u3048\u304a"}}}
****************ここまで*********************


データを受け取るFormはこんな感じ:
****************ここから*********************
1個目:
public class MainForm {
    public int type;
    public TitleForm titleForm;
}
2個目:
public class TitleForm {
    public int id;
    public String name;
    public String kikan;
    public String ext;
    public List<String> test;
    public OthersForm othersForm;
}
3個目:
public class OthersForm {
    public int no;
    public String name;
}

****************ここまで*********************

Formを受け取るActionはこんな感じ:
****************ここから*********************
public class SampleAction {

    /** 出力フォーム */
    @Resource
    @ActionForm
    public MainForm mainForm;

    @Execute(validator = false)
    public String getList() {
        System.out.println(mainForm.titleForm.othersForm.no);  // これで10が取得できる
        return null;
    }
}

****************ここまで*********************

今の所、S2JSONRequestProcessorクラスは、Actionのパッケージに入れていますが、HotDeployはの警告は出て無いから良いのかな…?

JSONIC用の情報が無かったので、個人メモ用に挙げておきます。


環境:
extjs-4.1.1
jsonic-1.3.0.jar
sa-struts-1.0.4-sp9.zip の中身


因みに、カスタマイズしたくないっ!って人は…
こんな感じに、"." ドットで区切ることで、こんなカスタマイズをしなくても
Formにデータが入ってくれます。(jsonData では無く、 params になっているので注意)
****************ここから*********************
Ext.Ajax.request({
    url      : url,
    method   : 'POST',
    params : {
        type : 1,
        title.id    : e.record.data.id,
        title.name  : e.newValues.name,
        title.kikan : e.newValues.kikan,
        title.ext   : e.newValues.ext,
        title.test  : ['aiueo', 'kakikukeko'],
        title.others.no: 10,
        title.others.name: 'あいうえお'
    },
    scope    : me,
    callback : me.callBackRequest
});

****************ここまで*********************

実際に送られるデータはこんな感じ:(fire bugs より)
****************ここから*********************
type=1&title.id=&title.name=&title.kikan=&title.ext=&title.test=aiueo&title.test=kakikukeko&title.others.no=10&title.others.name=%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A
****************ここまで*********************


さらに言うと、JavaScriptの例はExtjsを使っているけど、考えは一緒なのでjQuery や別のAjax でも同じです。要はパラメータの部分だけどうにかすれば良いと言う事です。



検索用:Seasar2 SAStruts JSON Form データが入らない データがFormに入らない 設定されない 受け取り方 受信方法 リクエスト request Java

コメント

このブログの人気の投稿

ヨドバシカメラの店舗購入履歴を見るには…

C# の WPF の DataGrid で 行を交互に背景色を変える+選択色を変える+カラムが無い所も変える…

Visual Studio の ホットリロードが動かない場合に確認するところ