最終更新日:190524 原本2012/06/02

サーブレットとJSP/HTMLのやりとり (2/5)

■Ajaxでサーブレットにアクセスする

それにしても、この「フォームを送信して値を渡す」というやり方は、あまり便利そうには見えません。サーブレットで、PrintWriterを使ってページを出力するのは非常に面倒くさいものです。やはり画面表示はHTMLやJSPを利用し、サーバー側の処理部分だけサーブレットを使う、というやり方が効率が良いでしょう。

一つの方法として思いつくのが、「Ajaxを利用する」というものでしょう。HTML内からAjaxでサーブレットにアクセスし、その結果を取得し表示する。これならサーブレット側は結果の値だけを出力すればいいことになります。表示はHTMLにまかせておけばいいのですから。

では、これはサンプルを作成して、それを見ながら説明をしていくことにしましょう。下のリスト欄に、簡単な例を挙げておきました。index.htmlと、MyGaeAppServletを使ったサンプルです。HTML内からAjaxでMyGaeAppServletにアクセスし、結果を受け取って表示するようになっています。

今回のサンプルでは、入力フォームに整数を入力すると、Ajaxにサーブレットにアクセスし、ゼロからその数字までの合計を計算して受け取り表示するようになっています。いろいろと数字を入力して動作を確かめてみてください。

では、流れを見てみましょう。まず、Ajax通信で利用するXMLHttpRequestオブジェクトの生成はcreateRequestという関数にまとめてあります。これを呼び出してXMLHttpRequestオブジェクトを用意し、openでアクセス先を指定してリクエストをオープンし、sendで必要な値を設定してアクセス開始しています。このあたりの処理については、JavaScriptのAjax通信についての話になるので省略します。
(※参考: http://libro.tuyano.com/index3?id=50003 )
さて、サーブレット側の処理ですが、これは実は先程のサンプルとほとんど違いはありません。唯一違うのは、

1. response.setContentType("text/plain"); となっている。HTMLではなく標準テキストを書き出している。
2. out.printlnする内容が、ただのテキストになっている。HTMLタグは一切ない。

――このぐらいでしょう(もちろん数字を計算する処理は新たに増えていますが……)。Ajaxの利用は、サーブレット側ではほとんど意識することはありません。基本的にJavaScript側の問題と考えてよいでしょう。

●プログラム・リスト●

*program list*
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
※index.html
 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <title>Hello App Engine</title>
    <style>
    h1 {
        font-size: 16pt;
        background: #AAFFAA;
        padding: 5px;
    }
    </style>
    <script type="text/javascript">
    function doAction(){
        var req =  createRequest();
        if (req == null){
            alert("実行できません!");
            return;
        }
        var s = document.getElementById('text1').value;
        req.open("post", "/mygaeapp", true);
        req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        req.onreadystatechange = function(){
            if (this.readyState == 4 && this.status == 200){
                var msg = document.getElementById('msg');
                msg.innerHTML = this.responseText;
            }
        }
        req.send("text1=" + encodeURIComponent(s));
        msg.innerHTML = "<<< please wait... >>>";
    }
         
       function createRequest(){
        var httplist = [
            function(){ return new XMLHttpRequest(); },
            function(){ return new ActiveXObjct("Msxml2.XMLHTTP"); },
            function(){ return new ActiveXObject("Microsoft.XMLHTTP"); }
        ];
        for(var i = 0;i < httplist.length;i++){
            try {
                var http = httplist[i]();
                if (http != null) return http;
            } catch(e){
                continue;
            }
        }
        return null;
    }
    </script>
</head>
 
<body>
    <h1>Hello App Engine!</h1>
    <p id="msg">※整数を入力:</p>
    <p name="msg"></p>
    <table>
        <tr>
            <td>入力</td>
            <td><input type="text" id="text1"></td>
        </tr>
        <tr>
            <td></td>
            <td>
                <button onclick="doAction();">送信する</button>
            </td>
        </tr>
    </table>
</body>
</html>
 
 
※MyGaeAppServlet.java
 
package com.tuyano.libro.mygaeapp;
 
import java.io.*;
import java.net.*;
 
import javax.servlet.http.*;
 
@SuppressWarnings("serial")
public class MyGaeAppServlet extends HttpServlet {
     
    public void doGet(HttpServletRequest request,
            HttpServletResponse response)
            throws IOException {
        response.setContentType("text/plain");
        request.setCharacterEncoding("utf8");
        response.setCharacterEncoding("utf8");
        PrintWriter out = response.getWriter();
        out.println("Hello, world!");
    }
 
    public void doPost(HttpServletRequest request,
            HttpServletResponse response)
            throws IOException {
        response.setContentType("text/plain");
        request.setCharacterEncoding("utf8");
        response.setCharacterEncoding("utf8");
        String param = URLDecoder.decode(request.getParameter("text1"),"utf8");
        int result = 0;
        try {
            int n = Integer.parseInt(param);
            for(int i = 1;i <= n;i++){
                result += i;
            }
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
        PrintWriter out = response.getWriter();
        out.println(result);
    }
}