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 통신에 대한 이야기가 되기 때문에 생략한다.

그런데, 서블릿 측의 처리하지만, 이것은 사실 먼저 번의 샘플과 거의 차이가 없다. 유일한 차이점은

  1. response.setContentType("text/plain");라고 되어 있다. HTML이 아닌 일반 텍스트를 써서 내보내고 있다.
  2. out.println하는 내용이 단순한 텍스트로만 되어 있다. HTML 태그는 일절 없다.

이 정도이다(물론 숫자를 계산하는 처리는 새로 증가하고 있지만…). Ajax 사용은 서블릿 측에는 거의 의식하는 것은 아니다. 기본적으로 JavaScript 측에서의 문제라고 생각해도 좋을 것이다.