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


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

Servlet + JSP + Beansの組み合わせ

 お馴染みなので、ここでは説明省略。

Servlet + Ajaxの組み合わせ

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

メリットその1

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

メリットその2

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

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

リクエストを行う側(javascript)

 同期・非同期通信を選択できますが、並列処理ではないので注意。
 並列処理については、javascriptのWebWorkerを使ってみたを参照。
 参考の様にリクエスト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>