LoginSignup
41

More than 3 years have passed since last update.

Java、JavaScript間でAjaxによるJSONデータ(オブジェクト)のやり取りをしたい!〜Spring編〜

Last updated at Posted at 2017-12-06

JSからJavaのコントローラにJSONデータを渡す

簡単なTODOアプリを作る際にJSONの受け渡しをおこなったので備忘録
jQueryでのAjax通信を利用しています

todo.js
/** データベースに新規追加. */
  function postItem(newContent) {

    let todo = {
      content: newContent
    };

    $.ajax({
      type: "post",
      url: contextPath + "/post",  //Controllerを呼び出すURLになっていればOK
      data: { jsonTodo: JSON.stringify(todo) }, //JSON(連想配列)を文字列に変換
      dataType: "json"
    }).then(function (result) {
      console.log('成功時の処理が書けます。下のように。');
      let content = result.content;
    }, function () {
      console.log('失敗時の処理が書けます');
    });

キモは JSON.stringify(対象のJSONを文字列に変換)

TodoController.java
    /**
     * 新規のTODOを追加する.
     * @param todo 新規投稿TODO
     * @return 更新の反映されたTODO
     */
    @ResponseBody //アノテーションにJSONエンコーダが内蔵されているのでJSにオブジェクトを直接リターンできる
    @PostMapping("/post")
    public Todo post(@RequestBody Todo todo) throws JsonParseException, JsonMappingException, IOException  {
        todoRepository.saveAndFlush(todo); // db更新
        return todo;
    }

JavaのコントローラからJSにオブジェクトを渡す

TodoController.java
    @ResponseBody //リターンしたオブジェクトをJSONで解釈できる文字列に自動変換してくれる
    @GetMapping("/find_all_asc")
    public List<Todo> findAllOrderASC(){
        List<Todo> todos = todoRepository.findAll(new Sort(Direction.ASC, "id"));
        return todos;
    }
todo.js
  /** TODOリスト初期化 */
  $.getJSON(contextPath + "/find_all_asc", null,
    function (data, textStatus, jqXHR) { //dataにJSONが詰まっている
    //取得したJSONで行いたい処理を記述できる
      data.forEach(todo => {
        console.log(todo.content);  
      });
    }
  );

AjaxのSetup(jQueryの記述入ってます)

JavaScript


$(function () {
    /**
     * layout.htmlから取得したコンテキストパス.
     * 例)/elabel/edit にアクセスしたい場合は「contextPath + 'elabel/edit'」がURLとして利用できる.
     */
    contextPath = $('#contextPath').val();
});

/**設定を変更したい場合は個別のAjaxメソッド内に記述してください. */
(function () {
    $.ajaxSetup({
        cache: false,
        /**一度使用したAjax通信のレスポンスをキャッシュさせない. */
        timeout: 15000,
        /**タイムアウト設定(暫定) */
        beforeSend: function (xhr, settings) {
            /**通信開始直前の処理 */
            setCsrfTokenToAjaxHeader();
            // showKurukuru();
        },
        success: function (data, status, xhr) {
            /**通信成功時の処理 */
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            /**通信失敗時の処理 */
            console.log("ajax通信に失敗しました");
            console.log("XMLHttpRequest : " + XMLHttpRequest.status);
            console.log("textStatus     : " + textStatus);
            console.log("errorThrown    : " + errorThrown.message);
        },
        complete: function (xhr, status) {
            /**通信完了時の処理(エラーか否かに関わらず) */
            //hideKurukuru();
        },
    });
})();

/**
 * Spring SecurityのCSRF対策によるトークンをajax通信のヘッダに埋め込める関数.
 * 利用するAjax通信の直前に呼び出す形で利用してください.
 */

function setCsrfTokenToAjaxHeader() {
    var token = $("meta[name='_csrf']").attr("content");
    var header = $("meta[name='_csrf_header']").attr("content");
    $(document).ajaxSend(function (e, xhr, options) {
        xhr.setRequestHeader(header, token);
    });
}

Thymeleaf


<meta name="_csrf" th:content="${_csrf.token}" />
<meta name="_csrf_header" th:content="${_csrf.headerName}" />
<input id="contextPath" type="hidden" th:value="${#request.getContextPath()}" />

参考記事

気の利くJSON.stringify (http://www.symmetric.co.jp/blog/archives/1568)
ajaxからjavaにPOST送信する参考記事
ajaxからjavaにPOST送信する(http://brissyu.blogspot.jp/2015/09/11spring-boot-web-ajax-csrf.html)
spring3 でjsonをPOSTで受け取る(http://ponkotsusechan.hatenadiary.jp/entry/2016/02/01/173000_1)

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
41