【JSP×Ajax】フォームの内容をsubmitせずに非同期通信(Ajax)したいときの処理

2019年1月18日Java, jQuery

JSPでフォームを送信した結果、Java(Servlet)側でエラーが起きても画面遷移をしないで(フォームの入力内容を保持したまま)メッセージやらを出力したいときの処理です。

バリデーションプラグインとかを入れてると、submitしたときに画面遷移するのを阻止してバルーンを出してくれるんですが、バリデーションをすり抜けてServlet側でDBアクセスや形式チェックでエラーになると、画面遷移してしまいます。

こりゃいかんということで、ServletでのDBアクセスも画面遷移しないようにします。

HTML

<form>
	<input type="text" name="text1" value="1">
	<button type="button" id="submit">登録</button>
</form>

jQuery

$('#submit').on('click', function() {
	// フォームをシリアライズ化してパラメータにつめる
	var params = $('form').serialize() + "&btn=regist";
	
	// 確認ダイアログ
	if (confirm('登録します。よろしいですか。')) {
		$.ajax({
			type     : 'POST',
			url      : 'PAGE1', // PAGE1.javaのServiceメソッドが呼ばれる
			data     : params,
			dataType : 'json', // レスポンスをJSONとしてパースする
		}).done( function(json) {
			if (json.result == "success") { // 正常完了時の処理
			
				alert('登録成功');
			
			} else if (json.result == "fail") { // Exception発生時の処理
			
				alert('登録失敗');
			
			}
		}).fail( function(jqXHR, textStatus, errorThrown) { // サーバ由来のエラー(404とか)
			
			alert('通信失敗');
			
		});
	}
});

Java

private void service(HttpServletRequest request, HttpServletResponse response) {
	
	// ボタン押下時のパラメータを存在チェック
	if (request.getParameter("btn") != null) {
		if (request.getParameter("btn").matches("regist")) {
			// 登録ボタンが押された場合
			
			boolean ret = regist(); // 登録処理を行う
			if(ret == null) { // 登録に成功
					LogManager.getLog().debug("Regist Data succeed.");
					resultMap.put("result", "success");
					
				} else { // 登録に失敗
					LogManager.getLog().warn("Regist Data Failed.");
					resultMap.put("result", "fail");
					resultMap.put("resultStr", ret);
				}
			}
			// マッパ(JSON <-> Map, List)
			ObjectMapper mapper = new ObjectMapper();
			String jsonStr = mapper.writeValueAsString(resultMap);
			
			response.setContentType("application/json;charset=UTF-8"); // ヘッダ設定
			PrintWriter pw = response.getWriter();// pwオブジェクト
			pw.print(jsonStr); // 出力
			pw.close();
			
			return;
		}
	}
	
	// --- 既存のserviceメソッド処理
	
}

$(‘form’).serialize()でform要素の中にある入力部品を「name=value」という書式で文字列に変換してくれます。
複数の要素があった場合は「name1=value1&name2=value2…」とつながっていきます。

つまり、これをURLパラメータとして送ってあげると、submitせずともsubmitしたときと同様のパラメータをServletに送れます。わあい。

AjaxとServletとの値の受け渡しはJson形式で行ってます。
PrintWiterでJson文字列を出力してからserviceメソッドをreturnすると、あら不思議、画面遷移せずにJavaの処理で作成した値が受け取れます。

JSPとAjaxを組み合わせるの、使い方次第ではかなり便利に使えそうです。

2019/2/21 サンプルソースがしょぼすぎたので改定しました。