응답 헤더정보 다루기

WEB2.0/ajax | 2006. 4. 11. 17:23
Posted by 시반

웹 프로그래밍에서는 브라우저의 요청에 응답을 해야 한다. 정상적인 응답이든 비정상이든 브라우저는 그 결과를 표시한다. 이번 주제는 AJAX 를 이용하여 서버의 상태만을 확인해 볼 수 있는 방법을 제시하고자 한다. 서버의 상태를 확인하기 위해서는 특정 리소스 url 로 요청을 보내면 된다. 하지만 서버는 응답정보를 브라우저에 보내게 되는데, 이럴경우에 응답정보의 모든 부분이 필요하지는 않는다. 단지 헤더정보만 얻을 수 있으면 서버의 상태를 파악할 수 있다.

 

지금까지 XMLHttpRequest 객체의 open(method, url, asynch) 메소드의 method 에는 GET 및 POST 만을 사용했었다. 하지만 HEAD 을 사용하면, 즉 브라우저가 HEAD 요청을 보내면, HEAD 요청을 받은 서버는 응답을 보낼때 body 의 내용은 빼버리고 헤더 정보만 채워서 보내게 된다. 따라서 오고가는 정보의 양이 극히 줄기때문에 브라우저에서 시간간격으로 서버의 상태를 점검하는데 아주 유용하게 사용할 수 있다.

 

이번 주제의 예제를 살펴보자.

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Reading Response Headers</title>

<script type="text/javascript">
var xmlHttp;
var requestType = "";

function createXMLHttpRequest() {
    if (window.ActiveXObject) {
        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    else if (window.XMLHttpRequest) {
        xmlHttp = new XMLHttpRequest();
    }
}
   
function doHeadRequest(request, url) {
    requestType = request;
    createXMLHttpRequest();
    xmlHttp.onreadystatechange = handleStateChange;
    xmlHttp.open("HEAD", url, true);
    xmlHttp.send(null);
}
   
function handleStateChange() {
    if(xmlHttp.readyState == 4) {
        if(requestType == "allResponseHeaders") {
            getAllResponseHeaders();
        }
        else if(requestType == "lastModified") {
            getLastModified();
        }
        else if(requestType == "isResourceAvailable") {
            getIsResourceAvailable();
        }
    }
}

function getAllResponseHeaders() {
    alert(xmlHttp.getAllResponseHeaders());
}

function getLastModified() {
    alert("Last Modified: " + xmlHttp.getResponseHeader("Last-Modified"));
}

function getIsResourceAvailable() {
    if(xmlHttp.status == 200) {
        alert("Successful response");
    }
    else if(xmlHttp.status == 404) {
        alert("Resource is unavailable");
    }
    else {
        alert("Unexpected response status: " + xmlHttp.status);
    }
}

</script>
</head>

<body>
  <h1>Reading Response Headers</h1>
 
  <a href="javascript:doHeadRequest('allResponseHeaders', 'readingResponseHeaders.xml');">Read All Response Headers</a>
 
  <br/>
  <a href="javascript:doHeadRequest('lastModified', 'readingResponseHeaders.xml');">Get Last Modified Date</a>
 
  <br/>
  <a href="javascript:doHeadRequest('isResourceAvailable', 'readingResponseHeaders.xml');">Read Available Resource</a>
 
  <br/>
  <a href="javascript:doHeadRequest('isResourceAvailable', 'not-available.xml');">Read Unavailable Resource</a>

</body>
</html>

<readingResponseHeaders.html 의 전체 소스>

 

<?xml version="1.0" encoding="UTF-8"?>

<readingResponseHeaders>

 

</readingResponseHeaders>

 

<readingResponseHeaders.xml 의 전체 소스>

 

 

지금까지 GET 혹은 POST 방식만을 사용해 예제를 작성했던 생각을 떠올려 볼때 이번 예제의 유일한 차이점은 xmlHttp.open("HEAD", url, true); 이다. HEAD 는 서버에 요청을 보낼때 HEAD 요청을 보내는 것으로 요청을 받은 서버는 body 의 정보를 아무것도 채우지 않고 단지 헤더 정보만을 넣어서 브라우저로 보내게 되다.

 

의심이 간다면 readingResponseHeaders.xml 파일에 내용을 채운후 아래와 같이 코드를 수정해서 실행해보자.

 

function getAllResponseHeaders() {
    alert(xmlHttp.getAllResponseHeaders());
    alert(xmlHttp.responseText);
    alert(xmlHttp.responseXML.getElementsByTagName("readingResponseHeaders")[0].firstChild.nodeValue);
}

 

첫번째 alert() 만 헤더정보를 표시하고 두번째, 세번째는 아무런 아무런 값도 없을 것이다.(open 메소드의 HEAD 를 GET 으로 수정한 후 다시 실행해 보면 두번째, 세번째 모두 값을 출력할 것이다.)

 

따라서 서버의 상태만을 점검하는 것이라면 HEAD 요청을 사용하는 것이 브라우저와 서버간 오고가는 데이터의 양이 매우 적어지기 때문에 서버에 부하를 최소화 하는 방식이라고 하겠다.

 

 


<서버의 응답정보 중 헤더정보만을 표시한 그림>

 

 


 

<서버의 헤더정보중 Last-Modified 항목에 대한 값>

 

 


 
<XHR 객체의 state 상태가 200 일 경우>
 
 
참고로 XHR 객체의 state 의 값이 200 이면 정상적인 서버 응답종료를 의미한다. 404는 해당 서버 리소스 url 이 존재하지 않음을 의미한다. 500이면 서버가 해당 요청을 수행하다가 내부적으로 에러가 발생했음을 의미한다.
 
 

 


 

<XHR 객체의 state 상태가 404 일 경우>

3장에서는 AJAX 의 여러가지 기본적인 특성에 대해서 공부하였다. 또한 아주 간단한 예제를 통해서 그 특징들이 어떻게 적용되는지도 살펴보았다. 이번 4장에서는 좀더 발전하여 실제적으로 쓰임새 측면에서 AJAX 를 다루어 보기로 한다.

 

실용적인 측면에서 AJAX 를 어떻게 활용할 수 있을지 살펴보자. 첫번째로 사용자가 브라우저의 입력폼에 값을 입력했을때 그 값을 검증하는 기능을 구현해볼 것이다. 이번 예제에서는 간단하게 날짜를 입력했을때, 그 값을 맞게 입력했는지 검증하는 로직을 AJAX 로 적용해 볼것이다. 여러 프로젝트를 수행한 결과 이런 폼 입력값 검증작업의 경우 간단한 것은 자바스크립트를 사용하면 아주 쉽게 끝나버린다. 오히려 서버의 로직을 거치지 않으므로 서버에 부담도 없다. 하지만 서버의 DB 나 혹은 XML 에 담겨진 데이타와 비교 혹은 검증을해야만 하는 경우엔 어쩔 수 없이 서버의 비지니스 로직을 거쳐야 한다. 하지만 이럴경우 코아 비지니스 로직을 수행하기 전에 입력폼의 값을 검증하는 로직을 추가로 코딩해야 해야만 한다. 또한 입력값이 잘못 되었다면 어떤입력값이 어떻게 잘 못되었다고 친절하게 알려주는 새로운 페이지로 이동해야 한다거나, 쉽게는 팝업처리를 할 수도 있다. 이렇게 되면 사용자는 또다시 처음부터 다시 입력을 해야하는 고생을 해야 한다.

 

이럴경우 AJAX 를 이용한 폼 입력값 검증작업을 해주면 비지니스 로직을 개발할때는 코어 로직만 작성하면 되고, 고객 입장에서는 입력한 값이 어디가 어떻게 잘못된건지 바로 알수 있기때문에 아주 유용한 방법이 될 것이다.

 

그럼 소스를 살펴보자. 코드가 길어지는 것을 방지하기 위해 되도록 소스는 단순하게 짜여졌다.

 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
  <head>
    <title>Using Ajax for validation</title>
 
    <script type="text/javascript">
        var xmlHttp;

        function createXMLHttpRequest() {
            if (window.ActiveXObject) {
                xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
            else if (window.XMLHttpRequest) {
                xmlHttp = new XMLHttpRequest();               
            }
        }

        function validate() {
            createXMLHttpRequest();
            var date = document.getElementById("birthDate");
            var url = "ValidationServlet?birthDate=" + escape(date.value);
            xmlHttp.open("GET", url, true);
            xmlHttp.onreadystatechange = callback;
            xmlHttp.send(null);
        }

        function callback() {
            if (xmlHttp.readyState == 4) {
                if (xmlHttp.status == 200) {
                    //var mes = xmlHttp.responseXML.getElementsByTagName("message")[0].firstChild.data;
     var mes = xmlHttp.responseXML.getElementsByTagName("message")[0].firstChild.data;
                    var val = xmlHttp.responseXML.getElementsByTagName("passed")[0].firstChild.data;
                    setMessage(mes, val);
                }
            }
        }
       
        function setMessage(message, isValid) {           
            var messageArea = document.getElementById("dateMessage");
            var fontColor = "red";
           
            if (isValid == "true") {
                fontColor = "green";               
            }
            messageArea.innerHTML = "<font color=" + fontColor + ">" + message + " </font>";
        }

    </script>
  </head>
  <body>
    <h1>Ajax Validation Example</h1>
    Birth date: <input type="text" size="10" id="birthDate" onchange="validate();"/>
    <div id="dateMessage"></div>
  </body>
</html>


<validateion.html 전체 소스 코드>

 

 

package ajaxbook.chap4;

import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;

import javax.servlet.*;
import javax.servlet.http.*;

public class ValidationServlet extends HttpServlet {   
   
    /** Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        PrintWriter out = response.getWriter();
       
        boolean passed = validateDate(request.getParameter("birthDate"));
        response.setContentType("text/xml");
        response.setHeader("Cache-Control", "no-cache");
        String message = "You have entered an invalid date.";
       
        if (passed) {
            message = "You have entered a valid date.";
        }
        out.println("<response>");
        out.println("<passed>" + Boolean.toString(passed) + "</passed>");
        out.println("<message>" + message + "</message>");
        out.println("</response>");
        out.close();
     }
   
    /**
     * Checks to see whether the argument is a valid date.
     * A null date is considered invalid. This method
     * used the default data formatter and lenient
     * parsing.
     *
     * @param date a String representing the date to check
     * @return message a String represnting the outcome of the check
     */
    private boolean validateDate(String date) {
       
        boolean isValid = true;
        if(date != null) {
            SimpleDateFormat formatter= new SimpleDateFormat("MM/dd/yyyy");
            try {
                formatter.parse(date);
            } catch (ParseException pe) {
                System.out.println(pe.toString());
                isValid = false;
            }
        } else {
            isValid = false;
        }
        return isValid;
    }
}

<ValidationServlet.java 의 전체 소스 코드>

 

 

이번 예제는 사실 설명이 불필요할 정도로 매우 간단하다. 브라우저에서는 날짜를 입력받는 필드만 있다. 날짜를 입력하고 난후 포커스가 빠져나가면 입력했던 날짜는 서버 프로그램으로 전송되고 입력된 값이 날짜 형식에 적절한지 판단해서 다시 브라우저로 보내주는 형식이다.

 

 


 

<날짜를 잘못 입력했을 경우>

 

 


 

<날짜 형식으로 입력했을 경우>

 

 

출처 : jinoxst님의 블로그

'WEB2.0 > ajax' 카테고리의 다른 글

Auto Refresh 기능 구현하기  (0) 2006.04.11
동적으로 리스트박스 구성하기  (0) 2006.04.11
폼 입력값 검증하기  (0) 2006.04.11
서버와 통신하기(요청/응답 처리)  (0) 2006.04.11
XMLHttpRequest 오브젝트 사용하기  (0) 2006.04.11
 
블로그 이미지

시반

시반(詩伴)이란 함께 시를 짓는 벗이란 뜻을 가지고 있습니다. 함께 나눌수 있는 그런 공간이길 바라며...

카테고리

분류 전체보기 (233)
개발 이야기 (73)
WEB2.0 (57)
DB2 (24)
MySQL (6)
오라클 (26)
기타 (44)
취미 (0)
잡담 (2)