質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.77%

Struts2のjson-pluginでjsonデータをpostで受け取りたい

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 5,498

score 149

前提・実現したいこと

struts-config.xmlでactionメソッドごとにresultでtype="json"を指定すると実現できるが、
convention-pluginを利用しているので同様なことをアノテーションで実現したいがうまく動作しない。
convention-plugin、json-pluginだけの、ZeroConfigurationで実現したい。

※他のアクションは全てアノテーションを使っているのでjsonデータのpostの部分だけ、
struts-config.xmlでの設定を併用はしたくなく、仕方がないので今は、postデータをjson形式ではなく
シリアライズした文字列としてサーバに渡し、json-pluginを使わずアクションメソッド内でjacksonで
自力でデシリアライズするようにしています。

発生している問題・エラーメッセージ

struts-config.xmlで指定した場合は、メソッドが呼ばれたときに、actionクラスで定義している
オブジェクトに自動でjsonデータが格納されている(List<POJOクラス>型のオブジェクト)
アノテーションの設定だけでやろうとしても上記のオブジェクトは、どうしてもnullになる。
※アノテーションでの同様の設定の仕方がわからない。

該当のソースコード

(java)
@ParentPackage("json-default")
@Results({
    @Result(name="json", type="json", params={"root","data", "noCache","true"}),
    @Result(name="exception", location="/exception.jsp")
})
public class SampleAction extends Action {
    private List<POJO> data; //with setter,getter

    @Action("set-data")
    //@Actioにresults={@Result(type="json",params={"enableSMD","true"})}を指定してもダメ
    public String setData() {
        System.out.println(data); //data=null(デシリアライズされない)
        return successValue;
    }
}

(jsp)
$("#button").click(function(e) {
    $.ajax({
        url: 'set-data.action',
        type: 'post',
        data: '{"data":' + JSON.stringify(arrayData) + '}',
        dataType: 'json',
        contentType:"application/json;charset=utf-8",
        success: function (res) {
            console.debug(res);
        }
    });
});

試したこと

struts-config.xmlで指定するとちゃんとオブジェクトにデシリアライズされる
(参考)http://stackoverflow.com/questions/19566700/how-to-use-jquery-to-post-json-data-to-a-struts2-action-class

(struts-config.xml)
<package name="sample.action" namespace="/" extends="json-default">
    <action name="set-data" class="sample.action.SampleAction" method="setData">
        <result type="json">
            <param name="enableSMD">true</param>
        </result>
    </action>
</package>
※<param name="enableSMD">true</param>は指定しなくても動作した。

補足情報(言語/FW/ツール等のバージョンなど)

struts2-2.3.20

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

check解決した方法

+2

struts.xmlによる定義と、@Actionなどの併用を色々試しましたがうまく動作しませんでした。
アノテーションを利用するのが今回の目的のため、頂いた回答をもとに、アノテーションだけの
設定で実現できました(struts.xmlには何も記述なし)
@Action内に、@Interceptorを設定する必要あり

(struts.xml)
  記述なし


(java)
 @ParentPackage("json-default")
 @Results({
    @Result(name="json", type="json", params={"root","data", "noCache","true"})
 })
 public class ConfigAction extends Pg2BaseAction {
    private List<POJO> data;

    @Action(value="set-data", interceptorRefs={@InterceptorRef(value="json", params={"enableSMD", "true"})})
    public String setData(){
        System.out.println(data);
        return success();
    }
 }


(jsp)
    $("#button").click(function(e) {
        $.ajax({
            url: 'set-data.action',
            type: 'post',
            data: '{"data":' + JSON.stringify(jsonArray) + '}',
            dataType: 'json',
            contentType:"application/json;charset=utf-8",

            success: function (res) {
                alert(res);
            }
        });
    });

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

AJAXの受け手となるActionに値を滑り込ませているのはJSONInterceptorなので、
このインターセプタに「enableSMD=true」を渡せば解決する?気がします。

手元に試せる環境がないので、無試験で申し訳ないですが、
「struts.xml」の「json-default」な定義部分に、ref設定してparam与えて、

<package name="jsonDefault" extends="json-default">
  <result-types>
    <result-type name="json" class="org.apache.struts2.json.JSONResult"/>
  </result-types>
  <interceptors>
    <interceptor name="json" class="org.apache.struts2.json.JSONInterceptor"/>
    <interceptor-stack name="ajaxDefaultStack">
      <interceptor-ref name="json">
        <param name="enableSMD">true</param>
      </interceptor-ref>
    </interceptor-stack>
  </interceptors>
  <default-interceptor-ref name="ajaxDefaultStack" />
</package>


の、ような書きっぷりでおそらく渡せると思います。

参考にしたのは、JSON Pluginの、Excluding propertiesの書きっぷりです。

重ねてですが、当方試験したわけではないので動かなかったらごめんなさい。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/12/28 15:31

    ご回答ありがとうございます。

    頂いた設定と@Actionアノテーションの併用ではうまくいきませんでした。
    (頂いた設定とstruts.xml内の<action>タグの設定だと動作いたします)

    アノテーションを利用するのが目的のため、回答頂いた方法を参考にして、
    別の方法で解決できましたので解決方法に記載いたします。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.77%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る