• 검색 결과가 없습니다.

JSON 을 활용하여 데이터를 서버로 보내기

 

바로 이전의 3-14 샘플은 브라우저의 파라미터를 XML 형식으로 변환하여 서버로 보내는 방법을 제시했 었다. 데이타 포맷의 표준이 되서버린 XML을 이용한다는 전체적인 맥락은 그럴싸했지만 사실 XML을 만 드는 과정이 복잡한 쿼리 스트링 조합작업이라면 누가 하려하겠는가 말이다. 나 자신도 이런 작업은 정말 싫어한다.

 

XML 을 생성하기 위한 javascript 날코딩의 대안으로 JSON(Javascript Object Notation, www.json.org) 을 소개한다. JSON 은 텍스트 포맷기반의 경량 데이터 변환 포맷이다. 프로그래밍 언어에 독립적며, C 언 어계열에 익숙한 데이터 구조 형식을 취하고 있다. JSON은 두가지 텍스트 포맷을 가지고 있는데, 첫번째 는 name/value 쌍의 컬렉션 데이터 구조로 프로그래밍 언어로 따지면 object, record, struct 쯤 되겠다.

두번째는 정렬된 value 의 리스트형태로써 프로그래밍 언어로 비유하자면 배열이라고 보면 될 것이다.

 

JSON 의 데이터 구조는 많은 프로그램 언어에 의해서 지원되고 있기때문에 XML 보다는 이기종 시스템간 의 이상적인 선택이 될 것이다. 추가적으로 JSON 은 표준 자바스크립트의 부류이므로 모든 웹 브라우저간 에도 양립할 수 있는 것이다.

 

<3-17 JSON 오브젝트구조도(출처 : www.json.org)>

   

위 그림은 JSON의 데이터 구조를 나타내고 있다.

 

Object는 {} 으로 표시한다. 오브젝트에는 name/value 쌍이 콜론(:)  혹은 콤마(,) 로 구분되어져 있으며 순서는 없다.

 

Array 는 [] 으로 표시한다. 배열은 정렬된 value 가 콤마(,) 에 의해서 구분되어져 있으며, value 값은 스 트링("" 으로 둘러싸야 함), 숫자, true or false, null, object , array 가 올수 있으므로 배열의 구조는 계 층적이라고 할 수 있다.

스트링은 유니코드 조합 및 백래쉬 이스케이프(₩)를 사용할 수 있으며 '' 을 사용하여 character 를 표현 할 수 있다.

스트링과 숫자는 C언어 혹은 자바의 스트링과 거의 흡사하지만 8진수 및 16진수 포맷은 지원하지 않는다.

공백을 name/value 쌍 사이사이에 사용할 수 있다.

 

하나의 예를 들어보자. Employ 라는 클래스(멤버로 firstName, lastName, employeeNumber, title)의 인 스턴스를 JSON 을 이용해서 아래와 같이 표현해 볼 수 있다.

 

var employee = {  "firstName"    : John,  "lastName"     : Doe,  "employNumber" : 123,  "title"        : "Manager"

}

 

그러면 위 표현을 오브젝트 속성을 이용해서 아래와 같이 다룰 수 있다.

var lastName = employee.lastName;//lastName 에 접근 var title = employee.title;//title 에 접근

employee.emplyeeNumber = 456;//employeeNumber 를 456 으로 수정  

JSON 의 인코딩은 확실히 XML 인코딩보다 가볍다. 따라서 네트웍을 통해서 큰 데이터가 오고가는 상황에 서는 많은 퍼포먼스의 차이가 발생할 것이다. JSON 싸이트에 가보면 적어도 14개 이상의 서버쪽 어플리케 이션을 다루는 프로그래밍언어에서 JSON 을 사용할 수 있게끔 준비가 되어 있다.

 

이제 3장의 마지막 주제인 JSON 을 이용한 간단한 샘플을 살펴보자.

 

<!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>JSON Example</title>

<script type="text/javascript" src="json.js"></script>

<script type="text/javascript">

var xmlHttp;

function createXMLHttpRequest() {     if (window.ActiveXObject) {

        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");

    }

    else if (window.XMLHttpRequest) {         xmlHttp = new XMLHttpRequest();

    } }    

function doJSON() {

    var car = getCarObject();

   

    //Use the JSON JavaScript library to stringify the Car object     var carAsJSON = JSON.stringify(car);

    alert("Car object as JSON:₩n " + carAsJSON);

   

    var url = "JSONExample?timeStamp=" + new Date().getTime();

   

    createXMLHttpRequest();

    xmlHttp.open("POST", url, true);

    xmlHttp.onreadystatechange = handleStateChange;

    xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");   

    xmlHttp.send(carAsJSON);

}    

function handleStateChange() {     if(xmlHttp.readyState == 4) {         if(xmlHttp.status == 200) {         parseResults();

        }     } }

function parseResults() {

    var responseDiv = document.getElementById("serverResponse");

    if(responseDiv.hasChildNodes()) {

        responseDiv.removeChild(responseDiv.childNodes[0]);

    }    

    var responseText = document.createTextNode(xmlHttp.responseText);

    responseDiv.appendChild(responseText);

}

function getCarObject() {

    return new Car("Dodge", "Coronet R/T", 1968, "yellow");

}

function Car(make, model, year, color) {     this.make = make;

    this.model = model;

    this.year = year;

    this.color = color;

}

</script>

</head>

<body>

  <br/><br/>

  <form action="#">

      <input type="button" value="Click here to send JSON data to the server"

        onclick="doJSON();"/>

  </form>

 

  <h2>Server Response:</h2>

  <div id="serverResponse"></div>

</body>

</html>

<3-18 jsonExample.htm 의 전체 소스 코드>

 

package ajaxbook.chap3;

import java.io.*;

import java.net.*;

import java.text.ParseException;

import javax.servlet.*;

import javax.servlet.http.*;

import org.json.JSONObject;

public class JSONExample extends HttpServlet {

 private static final long serialVersionUID = 1L;

 protected void doPost(HttpServletRequest request, HttpServletResponse response)     throws ServletException, IOException {

        String json = readJSONStringFromRequestBody(request);

        //Use the JSON-Java binding library to create a JSON object in Java         JSONObject jsonObject = null;

        try {

        jsonObject = new JSONObject(json);

        }

        catch(ParseException pe) {

        System.out.println("ParseException: " + pe.toString());

        }

        String responseText = "You have a " + jsonObject.getInt("year") + " "

        + jsonObject.getString("make") + " " + jsonObject.getString("model")         + " " + " that is " + jsonObject.getString("color") + " in color.";

        response.setContentType("text/xml");

        response.getWriter().print(responseText);

    }

    private String readJSONStringFromRequestBody(HttpServletRequest request){

        StringBuffer json = new StringBuffer();

        String line = null;

        try {

        BufferedReader reader = request.getReader();

        while((line = reader.readLine()) != null) {         json.append(line);

        }         }

        catch(Exception e) {

        System.out.println("Error reading JSON string: " + e.toString());

        }

        return json.toString();

    } }

<3-19 JSONExample.java 의 전체 소스 코드>

 

마지막 예제에서 중요한 부분을 굵게 표시하였다. 이번 예제를 실행해 보기 위해서는 json.js 와 자바관련 json 라이브러리가 필요하다. 관련 파일들은 json 웹싸이트에서 다운받으면 된다. 우선 자바스크립트쪽 핵 심코드를 먼저 살펴보자.

 

function getCarObject() {

    return new Car("Dodge", "Coronet R/T", 1968, "yellow");

}

function Car(make, model, year, color) {     this.make = make;

    this.model = model;

    this.year = year;

    this.color = color;

}  

위 코드는 설명이 별로 필요치 않을 것 같다. Car 객체를 만들어 주는 메소드이다.

 

function doJSON() {

    var car = getCarObject();

   

    //Use the JSON JavaScript library to stringify the Car object     var carAsJSON = JSON.stringify(car);

    alert("Car object as JSON:₩n " + carAsJSON);

   

    var url = "JSONExample?timeStamp=" + new Date().getTime();

   

    createXMLHttpRequest();

    xmlHttp.open("POST", url, true);

    xmlHttp.onreadystatechange = handleStateChange;

    xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");   

    xmlHttp.send(carAsJSON);

}

위 코드를 보면 자바스크립트 car 객체를 생성한 후 JSON 자바스크립트 라이브러이의 stringify 를 사용해 서 JSON 객체로 변환하고 있다. 나머지 로직은 POST 방식을 구현한 것이고 send(() 메소드에 JSON 객체 를 넣어준다.

 

이번엔 서버쪽 프로그램을 확인해 보자.

 

JSONObject jsonObject = null;

try {

    jsonObject = new JSONObject(json);

}

catch(ParseException pe) {

    System.out.println("ParseException: " + pe.toString());

}

String responseText = "You have a " + jsonObject.getInt("year") + " "

 + jsonObject.getString("make") + " " + jsonObject.getString("model")  + " " + " that is " + jsonObject.getString("color") + " in color.";

 

우선 서버 프로그램은 Http request 객체에서 JSON 문자열을 추출한다. 이렇게 추출된 문자열을 JSON 자 바 라이브러리의 JSONObject 클래스를 생성할때 생성자의 파라미터로 입력된다. JSONObject 는 자동으로 JSON 문자열을 파싱하고 getXxx 메소드를 이용해서 여러 타입의 데이터를 추출할 수 있는 것이다. 정말 간단하지 않은가?

 

다음은 3-19 샘플을 실행한 결과 화면이다.

 

 

Click here to send JSON data to the server 버튼을 클릭하면 alert 창으로 JSON object 데이터 구조 를 확인할 수 있다. 그리고 서버에서 처리된 결과문자열인 You have a 1968 Dodge Coronet R/T that is yellow in color. 을 확인 할 수 있을 것이다.

AJAX 강의 4-1장 - 폼 입력값 검증 하기

Chapter04-jinoxst.zip

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 의 전체 소스 코드>

   

이번 예제는 사실 설명이 불필요할 정도로 매우 간단하다. 브라우저에서는 날짜를 입력받는 필드만 있다.

날짜를 입력하고 난후 포커스가 빠져나가면 입력했던 날짜는 서버 프로그램으로 전송되고 입력된 값이 날 짜 형식에 적절한지 판단해서 다시 브라우저로 보내주는 형식이다.

 

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

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

AJAX 강의 4-2장 - 응답 헤더정보 다루기

웹 프로그래밍에서는 브라우저의 요청에 응답을 해야 한다. 정상적인 응답이든 비정상이든 브라우저는 그 결과를 표시한다. 이번 주제는 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);

}    

관련 문서