JSP/Servlet | サーブレットとJSP/HTML | Ajaxでサーブレットにアクセスする
先ほど説明した「フォームを送信して値を渡す」方式は、あまり便利とは言えない。サーブレットでPrintWriterを使ってページを出力するのは非常に面倒である。やはり画面表示にはHTMLやJSPを利用し、サーバー側の処理部分だけをサーブレットで行う方式のほうが効率がよい。
一つの方法として考えられるのがAjaxを使うことである。HTML内のAjaxからサーブレットへアクセスし、その結果を取得して表示する。こうすればサーブレット側は結果値だけを出力し、表示はHTML側で行うため、開発が楽になる。
それではサンプルを作り、それを見ながら説明しよう。以下に簡単な例を示す。
index.html
<!DOCTYPE html>
<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.devkuma.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);
}
}
index.htmlとMyGaeAppServletを使ったサンプルである。HTML内のAjaxからMyGaeAppServletにアクセスし、結果を受け取って表示するようになっている。
今回のサンプルでは、入力フォームに整数を入力するとAjaxでサーブレットへアクセスし、0からその数までの合計を計算して受け取り、表示する。いろいろな数値を入力して動作を確認してみよう。
流れを見てみよう。まずAjax通信で利用するXMLHttpRequestオブジェクトの生成はcreateRequestという関数にまとめられている。これを呼び出してXMLHttpRequestオブジェクトを取得し、openでアクセス先を指定してリクエストを開き、sendで必要な値を設定してアクセスを開始する。この部分の処理はJavaScriptのAjax通信の話になるため、ここでは省略する。
一方、サーブレット側の処理は、実は前回のサンプルとほとんど違いがない。唯一の違いは次の点である。
response.setContentType("text/plain");となっている。HTMLではなく通常のテキストを書き出している。- out.printlnする内容が単純なテキストだけになっている。HTMLタグは一切ない。
この程度である。もちろん数値を計算する処理は新しく増えているが、Ajaxの利用はサーブレット側ではほとんど意識するものではない。基本的にはJavaScript側の問題だと考えてよい。