ServletとAjaxの組み合わせについて考える

　javaでWebアプリケーションと言えば、MVCモデル(Servlet + JSP + Beans)しか知らなかった。
最近、**Servlet + Ajax**の組み合わせがあることを知りったので、記録しておく。**javascriptからServletを呼び出せる**のが特徴である。

## Servlet + JSP + Beansの組み合わせ
　お馴染みなので、ここでは説明省略。

![java7.jpg](https://qiita-image-store.s3.amazonaws.com/0/207458/022103e7-dbbe-38e3-20d0-b8c0675ef293.jpeg)


## Servlet + Ajaxの組み合わせ

![java8.jpg](https://qiita-image-store.s3.amazonaws.com/0/207458/d9b554d4-c3ec-3521-a5b8-562b5545cdee.jpeg)


　上図だけ見るとあまり違いは無い様に思えるが、Servlet + Ajaxの場合は**レスポンスをjavascriptが受け取る**ので、いちいち画面を更新する必要が無い。

##メリットその１
　例えば、下記の様にservletを通して**間接的にjavascriptからDBにアクセスすることが出来る**。大量のデータを扱う場合、DBからデータを小出しに取り出すことも出来る。

![java9.jpg](https://qiita-image-store.s3.amazonaws.com/0/207458/942c4299-c57b-c0ae-6ba4-f33d39cfff75.jpeg)

##メリットその２
　JSPと比べると下記の理由により、**フロントとバックの独立性が高まる**ので開発が行いやすくなる（ケースもある）。JSONの形式を決めておけばやり取りは可能である。

　・**呼び出し側は、基本的にhtml + jQueryでOK**
　　→**ページにbeansやクラスの宣言が必要なくなる**
　・**やり取りはJSONのみ**
　・**画面の更新が不要**
　・**下図の様に複数呼び出しも可**

![java10.jpg](https://qiita-image-store.s3.amazonaws.com/0/207458/c447e69c-539c-6912-044f-a454938c1393.jpeg)


## リクエストを行う側（javascript） ##
　同期・非同期通信を選択できますが、並列処理ではないので注意。
　並列処理については、[javascriptのWebWorkerを使ってみた](https://qiita.com/qiiChan/items/5179a7e540257d38c181)を参照。
　[参考](http://blog.codebook-10000.com/entry/20130930/1380507089)の様にリクエストJSON自体を1つの要素の値として送信しても良いようです。

````sample.js

function sampleAjax() {

  //リクエストJSON
  var request = {
    param1 : "param",
    param2 : 12345
  };

  //ajaxでservletにリクエストを送信
  $.ajax({
    type    : "GET",          //GET / POST
    url     : "http://localhost:8080/SampleWeb/urlServlet",  //送信先のServlet URL（適当に変えて下さい）
    data    : request,        //リクエストJSON
    async   : true,           //true:非同期(デフォルト), false:同期
    success : function(data) {
      //通信が成功した場合に受け取るメッセージ
      response1 = data["response1"];
      response2 = data["response2"];
    },
    error : function(XMLHttpRequest, textStatus, errorThrown) {
      alert("リクエスト時になんらかのエラーが発生しました：" + textStatus +":\n" + errorThrown);
    }
  });

}

````

## リクエストを受け取る（Servlet） ##
　DB呼び出しなども可能。

````sampleServlet.java
package servlet;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(urlPatterns={"/urlServlet"})
public class SvDbViewRange extends HttpServlet {

    private static final long serialVersionUID = 1L;

    @Override
    public void doGet (HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {

    try {

        //パラメータ取得
        String param1 = req.getParameter("param1");
        String param2 = req.getParameter("param2");

        //処理（DB呼び出し等）
        String response1 = "";
        String response2 = "";

        //出力(レスポンスをmapに格納してJSON化)

        //JSONマップ
        Map<String, String> mapMsg = new HashMap<String, String>();

        //追加
        mapMsg.put("response1", response1);
        mapMsg.put("response2", response2);

        //マッパ(JSON <-> Map, List)
        ObjectMapper mapper = new ObjectMapper();

        //json文字列
        String jsonStr = mapper.writeValueAsString(mapMsg);  //list, map

        //ヘッダ設定
        res.setContentType("application/json;charset=UTF-8");   //JSON形式, UTF-8

        //pwオブジェクト
        PrintWriter pw = res.getWriter();

        //出力
        pw.print(jsonStr);

        //クローズ
        pw.close();

    } catch(Exception e) {
        e.printStackTrace();
    }

    }

}

````

## ObjectMapperのMaven ##

下記をpom.xmlに追記する。

````pom.xml

  <dependencies>
    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.5</version>
    </dependency>
  </dependencies>
````