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

## JSからJavaのコントローラにJSONデータを渡す
簡単なTODOアプリを作る際にJSONの受け渡しをおこなったので備忘録
jQueryでのAjax通信を利用しています




```js: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を文字列に変換)



```java: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にオブジェクトを渡す
```java:TodoController.java
    @ResponseBody //リターンしたオブジェクトをJSONで解釈できる文字列に自動変換してくれる
	@GetMapping("/find_all_asc")
	public List<Todo> findAllOrderASC(){
		List<Todo> todos = todoRepository.findAll(new Sort(Direction.ASC, "id"));
		return todos;
	}
```


```js: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
```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
```html

<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)