JSON - JSON API 사용하여 JSON표기 쉽게 처리 하기

Published on: 2009. 7. 15. 01:02 by louis.dev

앞에서 살펴본 JSON표기법을 기본으로 하여 사용자가 직접 JSON의 표기법을 선언해 사용할 수 있다. 하지만 전달될 데이터가 복잡해 지고 다양해 지면서 개발자가 직접 JSON 표기법에 맞추어 제작하기는 매우 힘들다. 그렇기 때문에 www.json.org 에서 제공하는 API를 통해 개발자 들은 직접 JSON표기법으로 JSON데이터를 구성하지 않고 만들수 있다.

1. JSON API 다운로드 받기

http://www.json.org 페이지의 하단 부분의 json-simple 이란 부분을 클릭한다.

상단의 download를 클릭하면 json Library를 다운 받을 수 있다.
JSON의 document를 보려면 org.json 을 클릭하면 문서를 확인 할 수 있다.

2. JSON의 구조

Ajax방식으로 스크립트에서 JSON ENGINE을 호출하면 JSON ENGINE은 DB에 접근 하는 java class를 호출 하여 DB에서 데이터를 가져오게 된다.
이때 가져온 데이터를 JSON API를 통해 JSON방식으로 데이터를 생성하고 view페이지로 텍스트 방식으로 넘긴다. 그리고 그 데이터를 다시 자바스크립트로 보내게 되는 루트를 가진다.
여기서 가장 중요한 것은 view 페이지의 json데이터는 반드시 text 형식으로 설정되어야 한다는 것이다.

<%@ page  contentType="text/plain; charset=EUC-KR"%>

3. 작성방법
1) object 형식으로 데이터를 받아 사용하는 방식

① 블로그에 올린 HttpRequest.js 파일의 sendRequest function을 통해 Ajax방식으로 JavaClass로 접근한다.
sendRequest("cartjson.action", param, jsonCartObject, "POST");
cartjson.cation : javaclass파일 호출
jsonCartObject : callback 함수 호출

② javaClass에서 JSON API를 통해 JSON객체 생성
public String createJSONObject(){
   SalesCartBean bean = getCartBean();
   
   JSONObject obj = new JSONObject();  //json을 사용하기 위한 객체 생성
   obj.put("goods", bean.getGoods());   //앞은 key 뒤는 value
   obj.put("qty", bean.getQty());
   obj.put("cost", bean.getCoststr());
   obj.put("amount", bean.getAmountstr());
  
   JSONObject outer = new JSONObject(); //
   outer.put("cartlist", obj);      //session의 cartlist를 obj에 넣는다.
   System.out.println(outer);
   return outer.toString();
 }

다음과 같이 JSONObject 인스턴스를 생성하여 put() method로 key와 value를 넣어주고 있다.
그리고 하단에서 outer라는 이름의 JSONObject 인스턴스를 생성해 위에서 생성한 obj를 넣어주고 있다. 즉 다음과 같이 하면 JSON의 표기법은
cartlist : {
"obj" : {
          "goods" : "bean.getGoods()데이터",
          "qty" : "bean.getQty() 데이터",
          "cost" : "bean.getCoststr()의 데이터",
          "amount" : "bean.getAmountstr()의 데이터"
          }
}


다음과 같은 형태가 된다.

③ 데이터를 전달 받은 view page는

<%@ page  contentType="text/plain; charset=EUC-KR"%>

${jsoncart}

이런식으로 설정해 주고 다시 callback method를 실행 시켜 JSON데이터를 끄집어 낸다.

function jsonCartObject(){
   if(httpRequest.readyState == 4) {
      if (httpRequest.status == 200) {
        var json = eval('(' + httpRequest.responseText + ')');  //json정보는 text로 가져온다. eval의 ()안의 것은 method가 된다.
        var tableID = document.all.salesbody;
        var row=tableID.insertRow(1);
        row.bgColor="ffffff";
        row.height="24";
        row.align="center";
        row.insertCell().innerText=json.cartlist.goods;  //insertCell() : 행을 나눈다(javascript function).전달받은 json데이터의 데이터를 가져온다.
        row.insertCell().innerText=json.cartlist.qty;
        row.insertCell().innerText=json.cartlist.cost;
        row.insertCell().innerText=json.cartlist.amount;
       }
     }
  } 

다음과 같은 방식으로 json데이터를 가져온다.

2) Array를 사용하여 JSON데이터 생성
① 블로그에 올린 HttpRequest.js 파일의 sendRequest function을 통해 Ajax방식으로 JavaClass로 접근한다.
sendRequest("cartjson.action", param, jsonCartArray, "POST");

② JAVA Class에서 데이터를 전송받아 JSON객체 생성

public String createJSONArray(){
  JSONArray inner = new JSONArray();
   for(int i = 0; i < cartlist.size(); i++){
     SalesCartBean bean = cartlist.get(i);
     JSONObject obj = new JSONObject();
     obj.put("goods", bean.getGoods());
     obj.put("qty", bean.getQty());
     obj.put("cost", bean.getCoststr());
     obj.put("amount", bean.getAmountstr());
     inner.add(obj);
  }
  JSONObject outer = new JSONObject();
  outer.put("cartlist", inner);
  System.out.println(outer);
  return outer.toString();
 }

JSONArray 객체를 생성한다. 그리고 list형인 cartlist라는 collection을 가져와서 JSONObject 형에 넣어주고 inner라는 Array형에다가 넣어준다.
또 마지막으로 Object형으로 선언한 outer에다가 inner를 넣어주면서 배열형식으로 변환한다.

즉 다음과 같은 형태는 JSON표기법으로 다음과 같이 표현된다.
 {cartlist : 
       [ 
         {
          "goods" : "노트북",
          "gty" : 2,
          ...
         },
         {
           "goods" : "노트북",
            "gty" : 2,
            ...
          },
        ]
   }

③ callback function에서 전송된 json객체를 처리한다.

function jsonCartArray(){
     if(httpRequest.readyState == 4) {
      if (httpRequest.status == 200) {
     var json = eval('(' + httpRequest.responseText + ')');
        var sid  = document.getElementById("salesbody");
        if(sid.rows.length>1){
      for (k=sid.rows.length-1; k >= 1 ; k--){
       sid.deleteRow(k);  //노드를 삭제 한다.
      }
     }
     for(i=0; i< json.cartlist.length; i++){
      oRow = document.createElement('tr');        
      oCel0 = document.createElement('td');
      oCel1 = document.createElement('td');
      oCel2 = document.createElement('td');
      oCel3 = document.createElement('td');
       
      //oRow.style.textAlign='center';
      oRow.height='24';
      oRow.bgColor="ffffff";
            
      oCel0.className='cel0';
      oCel1.className='cel1';
      oCel2.className='cel2';
      oCel3.className='cel3';
      
      oRow.appendChild(oCel0);
      oRow.appendChild(oCel1);
      oRow.appendChild(oCel2);
      oRow.appendChild(oCel3);
      
      oCel0.style.textAlign='center';
      oCel1.style.textAlign='center';
      oCel2.style.textAlign='right';
      oCel3.style.textAlign='right';
      
      oCel0.innerHTML=json.cartlist[i].goods;
      oCel1.innerHTML=json.cartlist[i].qty;
      oCel2.innerHTML=json.cartlist[i].cost+'&nbsp;&nbsp;';
      oCel3.innerHTML=json.cartlist[i].amount+'&nbsp;&nbsp;';
      
      document.getElementById('salesbody').children(0).appendChild(oRow);
     }
       }
     }
    }
  
다른부분은 로직부분이기때문에 볼 필요 없고 색 있는 곳을 보면 cartlist를 배열형식으로 접근하고 있다.

JSON - JSON 표기법의 기본

Published on: 2009. 7. 15. 00:24 by louis.dev


1. object 방식
1) object 출력
<script language="JavaScript">
<!--
  var myJSONObject = {
    "test" : "hello"
  }
//-->
</script>
<form>
  <input type = "button" onclick="alert(typeof myJSONObject)" value="click">
</form>

출력결과 : object형태이기 때문에 "object" 가 출력된다.

2) property 출력
<script language = "JavaScript">
<!--
  var myJSONObject2 = {
    "test": "hello"
  }
//-->
</script>
<form>
  <input type = "button" onclick = "alert( myJSONObject2 )" value = "click">           <!-- 출력결과 : object Object -->
  <input type = "button" onclick = "alert( myJSONObject2.test )" value = "click">     <!-- 출력결과 : hello -->
  <input type = "button" onclick = "myJSONObject2.test = 'new test' ; alert(myJSONObject2.test )" value = "click">  <!--출력결과 : new test -->
  <input type = "button" onclick="alert(myJSONObject2.test)" value="click"/>          <!-- 출력결과 : hello -->
</form>

세번째줄과 같이 myJSONObject2.test에 새로운 문자열 new test를 입력하고 출력하면 new test가 출력 되지만 다시 출력하면 JSON에서 선언한 기본 데이터인 hello가 출력된다.

3) property가 두개 이상인 경우

<script language="JavaScript">
<!--
  var myJSONObject3 = {
    "test1": "hello1",
    "test2": "hello2", 
    "test3":"hello3"
  }
//-->
</script>
<form>
  <input type="button" onclick="alert(myJSONObject3.test1)" value="click">     <!-- 출력결과 : hello1 -->
  <input type="button" onclick="alert(myJSONObject3.test2)" value="click">     <!-- 출력결과 : hello2 -->
  <input type="button" onclick="alert(myJSONObject3.test3)" value="click">     <!-- 출력결과 : hello3 -->
</form>

각각의 property들은 ,(콤마) 로 구분한다.

4) 메소드 방식
<script language="JavaScript">
<!--
  var myJSONObject4 = {
    "test1" : "function() { alert('This is method test1') }"
  }
//-->
</script>

<form>
  <input type="button" onclick="eval('a=' + myJSONObject4.test1); a()" value="click">  <!-- 출력결과 : This is method test1 -->
</form>

eval은 javascript 메소드로서 전달인자를 function 으로 사용할 수 있게 한다.  a= 에 test1의 메소드가 대입되고 a(); 란 명령으로 json의 test1 function을 호출한다.

5) 메소드 방식(전달 인자가 있을 때)
<script language="JavaScript">
<!--
  var myJSONObject5 = {
    "test2" : "function(arg) { alert('This is argument : ' + arg) } "
  }
//-->
</script>
<form>
  <input type="button" onclick="eval('var a=' + myJSONObject5.test2 + ''); a('hello');" value="click">
  <input type="button" onclick="eval('(' + myJSONObject5.test2+')(\'hello\')');" value="click">
</form>

둘다 모두 hello가 출력된다.

6) 중첩된 object
<script language="JavaScript">
var obj7 = {
    "test" : {
      "name" : "k2club",
      "id" : 123
    }
  }
</script>
<input type="button" onclick="alert(typeof obj7.test)" value="click"> 
<input type="button" onclick="alert(obj7.test.name)" value="click">     <!-- 출력결과 : k2club -->
<input type="button" onclick="alert(obj6.test.id)" value="click">           <!-- 출력결과 : 123 -->

object는 name/value 쌍들의 비순서화된 SET이다. object는 { (좌 중괄호)로 시작하고 } (우 중괄호)로 끝내어 표현한다. 각 name 뒤에 : (colon)을 붙이고 , (comma)로 name/value 쌍들 간을 구분한다.

2. Array 방식
1)1차원 배열
<script language="JavaScript">
<!--
  var obj5 = [
    "test"
  ]
//-->
</script>

<input type="button" onclick="alert(typeof obj5[0])" value="click">
<input type="button" onclick="alert(obj5[0])" value="click">


2) 2차원 배열
<script language="JavaScript">
<!--
  var obj6 = {
    "test" : [
      "ccc", "ddd"
   
  }
//-->
</script>

<input type="button" onclick="alert(obj6.test[0])" value="click">   <!-- 출력결과 : ccc -->
<input type="button" onclick="alert(obj6.test[1])" value="click">   <!-- 출력결과 : ddd -->
다음과 같이 배열은 [] 으로 표현하며 [index]로 접근할 수 있다.

JSON - JSON의 기본

Published on: 2009. 7. 14. 23:48 by louis.dev

Ajax를 통한 데이터 전송 방식은 Text를 전송하는 방식과 XML데이터를 전송하는 방식 두가지가 있다.

하지만 XML데이터까지도 데이터를 문자열화 해서 노드 검색을 통해 데이터를 얻어오는 구조를 가지게 된다.

이렇게 문자열화 된 데이터를 객체화 하는 방법이 바로 JSON이다.(www.json.org)

JSON은 key : value 형식으로 데이터를 전송한다.

1. JSON의 기본
JSON을 표현하는 방법은 Object 방식과 Array방식 두가지가 존재한다.

1)object 방식


위의 그림과 같이 object의 구분은 {}(중괄호)로 시작하고 끝나면 key : value 의 구조를 가지고 한개의 데이터가 끝나면 다음 데이터와의 구분은 ,(콤마)로 구분한다.
예) var obj = {
                          "name" : "StYle_jG",
                          "number" : 1000
                   }

다음과 같은 형식으로 데이터를 전송한다.
각각의 값에 접근하려면 objectName.key 로 접근한다. 즉
obj.name 으로 접근하면 StYle_jG라는 데이터를 얻을 수 있다.

2) Array 방식


Array방식은 각각의 데이터를 인덱스로 조작할 수 있다.
array 방식은 [](대괄호)로 데이터를 구분하며 value 와 value 사이는 ,(콤마)로 구분한다.

위에 두가지 방법에서의 value는 다음과 같은 데이터형을 가질 수 있다.



value의 데이터 형은 Strign, number, object, array 뿐만 아니라 true,false와 같은 boolean값과 null 값도 포함한다.

그중의 String형 데이터를 보면



다음과 같은 구조를 가진다.

String의 구조는 문자열 시작과 끝에 " " 을 포함하는 Zero 이상의 UniCode의 집합이다. String형은 C나 JAVA와 같이 \(역슬러시)를 제공하고 위와같이 \b(backspace), \f(formfeed), \n(newline), \r(carriage return), \t(horizontal tab), \u (16진수)  와 같은 형태도 지원한다.

또한 데이터중 number형식은



다음과 같은 구조를 가진다.
JSON의 number형식은 8진수, 16진수를 사용하지 않는 점을 제외하면 C나 JAVA와 똑같은 특징을 가진다.
부호는 마이너스 값일때 - 를 붙이고 양수 일때는 아무것도 붙이지 않는다.
소수점은 e-30,E+20 과 같은 C나 JAVA에서 표현법과 똑같이 사용한다.

Ajax - XSLT 사용하기

Published on: 2009. 7. 13. 15:40 by louis.dev


Ajax를 사용할때 보통은 xml데이터를 사용하고 노드 탐색을 하여 데이터를 검출한뒤 사용할 곳에 직접 넣어 사용하는 방식을 취한다.

이렇게 되면 직접 style-sheet를 선언해야 하고 또한 매우 복잡한 형태가 된다.

그래서 XSLT 사용한다. XSLT는 실제적으로 보면  XML 데이터지만 거기에 html과 같은 태그와 함께 style-sheet까지 적용되어서 xml데이터만 연동할때 보다 훨신 편하게 xml데이터를 적용할 수 있게 된다.


다음 그림은 struts 2와 Ajax의 실행 순서를 그린 그림이다.
① fun1() function이 실행 되면 Ajax Engine으로 가서 다음과 같은 로직을 탄다.
② 모든 데이터를 수행하면 response XML을 통해 XML데이터를 리턴하게 된다.
③ XML 파일은 callback함수로 넘어간다.
④ fun2() function은 fun3() function을 호출하여 xsl 파일을 호출하고 XSLT로 가서 UI를 생성하고 그 데이터를 fun4() funtion으로 리턴하게 된다.

작업순서

1. xml 파일이 xsl로 가야 하기 때문에 XML을 만드는 작업을 먼저 해야 한다.

var xmlDoc = null; //변수 하나는 xml을 얻기 위해
var xslDoc = null; //xsl을 얻기 위해
 
  function loadList(num,goods) { //goods 파일 이름
      qty = document.buyform.qty[parseInt(num)].value;
      if(parseInt(qty) > 10 || parseInt(qty) < 1){
       alert('1 ~ 10개까지 구입이 가능합니다.');
       document.buyform.qty[parseInt(num)].focus();
       return;
      }
   param = "goods="+goods+
        "&name="+document.buyform.name.value +
        "&qty="+qty;
   sendRequest("cart.action", param, loadedCartXML, "POST");  //sendRequest는 httpRequest.js 에 있는 method
                                                                                                         //cart.action으로 데이터를 전송하고 다음 메소드인 loadedCartXML 
                                                                                                         //을 callback한다.
  }
  
  function loadedCartXML() {
   if (httpRequest.readyState == 4) {
    if (httpRequest.status == 200) {
     xmlDoc = httpRequest.responseXML;                     //전송된 xml데이터를 xmlDoc라는 변수에 저장한다.
     sendRequest("cart.xsl", null, loadedCartXSL, "POST");      //xsl파일로 이동하고 callback으로 loadCartXSL로 이동한다.
    }
   }
  }
  function loadedCartXSL() {
   if (httpRequest.readyState == 4) {
    if (httpRequest.status == 200) {
     xslDoc = httpRequest.responseXML;                                 //xsl에서 수행한 데이터도 xml데이터기 때문에 responseXML로 받는다.
     doXSLT();
    }
   }
  }
  
  function doXSLT() {
   if (xmlDoc == null || xslDoc == null) return;
   
   var list = document.getElementById("cartList");
//internet explorer 일때
   if (window.ActiveXObject) {
    list.innerHTML = xmlDoc.transformNode(xslDoc);                  //transformNode()메소드로 xsl결과를 출력한다.
//explorer가 아닐때  
 } else {
    var xsltProc = new XSLTProcessor();
    xsltProc.importStylesheet(xslDoc);
    var fragment = xsltProc.transformToFragment(xmlDoc, document);
    list.appendChild(fragment);
   }
  }

2. xsl파일이 XSLT로 가려면 중간에 DTD문서가 존재해야 한다.(DTD문서는 확장자는 dtd, xsl파일이름과 같은 경로,같은 이름이어야 한다)
xml 데이터가 다음과 같다면
-------------------------------------------------------------------------------------------
<?xml version="1.0" encoding="euc-kr" ?>
<%@ page contentType="text/xml; charset=EUC-KR"%>
<%@ taglib prefix="s" uri="/struts-tags"%>

<cartlist>
 <s:iterator value="cartlist">
  <cart id="${filename}">
   <goods>${goods}</goods>
   <qty>${qtystr}</qty>
   <cost>${coststr}</cost>
   <amount>${amountstr}</amount>
   <filename>${filename}</filename>
     </cart>
 </s:iterator>
  <qtysum>${qtySum}</qtysum>
  <amountsum>${amountSumstr}</amountsum>
</cartlist>
-------------------------------------------------------------------------------------------
dtd문서는
-------------------------------------------------------------------------------------------
<?xml version="1.0" encoding="euc-kr"?>

<!ELEMENT cartlist (cart*)> <!-- cartlist안에 cart라는 eliment *(0개 이상) -->
 <!ELEMENT cart (goods, qty, cost, amount, filename*, qtysum*, amountsum*)> <!-- cart 라는 element들은 ()안과 같은 노드들을 가지고 있다. *는 0개 이상이란 뜻 -->
   <!ELEMENT goods (#PCDATA)>
  <!ELEMENT qty (#PCDATA)><!--pcdata: 값을 가지고 있다. -->
  <!ELEMENT cost (#PCDATA)>
  <!ELEMENT amount (#PCDATA)>
  <!ELEMENT filename (#PCDATA)>
  <!ELEMENT qtysum (#PCDATA)>
  <!ELEMENT amountsum (#PCDATA)>
<!ATTLIST cart id CDATA #REQUIRED> <!-- card id가 존재하는데 #REQUIRED로 (꼭필요하다)-->

-------------------------------------------------------------------------------------------
다음과 같이 설정한다.


3. 실제 UI가 발생할 xsl파일을 생성한다.
cart.xsl
-------------------------------------------------------------------------------------------
<?xml version="1.0" encoding="euc-kr" ?>
 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method = "html" indent="yes" encoding="euc-kr" />
  <xsl:template match="cartlist"> <!-- dtd문서에서 cartlist를 연결시켜줌 -->
<!-- 가장 최상위 eliement를 설정해 준다. -->
    <table border="0" cellpadding="0" cellspacing="1" bgcolor="#c0c0c0">
     <tr height="24" bgcolor="#f0f0f0">
       <td width="50" align="center"><span style="font:10pt"><b>선택</b></span></td>
       <td width="100" align="center"><span style="font:10pt"><b>상품명</b></span></td>
       <td width="52" align="center"><span style="font:10pt"><b>수량</b></span></td>
       <td width="90" align="center"><span style="font:10pt"><b>구입단가</b></span></td>
       <td width="95" align="center"><span style="font:10pt"><b>구입금액</b></span></td>
     </tr>
     <xsl:for-each select="cart">
   <tr height="24" bgcolor="#ffffff">
    <td align="center">
     <span style="font:10pt">
        <input type="checkbox" name="items" value="{filename}"/> 
     </span>
    </td>
   <td align="center">
      <a href="javascript:cartInfo('{filename}','{qty}','{cost}','{amount}')">
       <span style="font:10pt"><xsl:value-of select="goods"/></span>
      </a>  
    </td>
      
    <td align="center"><span style="font:10pt"><xsl:value-of select="qty"/></span></td>
    <td align="right"><span style="font:10pt;padding-right:5px"><xsl:value-of select="cost"/></span></td>
    <td align="right"><span style="font:10pt;padding-right:5px"><xsl:value-of select="amount"/></span></td>
   </tr>   
  </xsl:for-each>
   <tr height="24" bgcolor="#f0f0f0">
    <td align="center"><input type="button" value="삭제" onclick="delproc()"/></td>
    <td align="center"><span style="font:10pt"><b>항목별 합계</b></span> </td>
    <td align="center">
       <span style="font:10pt; color:#ff795a">
      <xsl:value-of select="qtysum"/>
       </span>
    </td>
    <td align="center"><span style="font:10pt">-</span> </td>
    <td align="right">
       <span style="font:10pt; color:#ff795a;padding-right:9px">
       <xsl:value-of select="amountsum"/>
       </span>
    </td>
   </tr>
 </table>
  </xsl:template>
</xsl:stylesheet>
-------------------------------------------------------------------------------------------
- for-each : 반복되는 데이터를 가져온다.
value-of select = xml문서의 다음과 같은 이름의 데이터를 가져온다.

Ajax XMLHttpRequest Object 생성 Util

Published on: 2009. 7. 13. 15:00 by louis.dev


function getXMLHttpRequest() {
 if (window.ActiveXObject) {
  try {
   return new ActiveXObject("Msxml2.XMLHTTP");
  } catch(e) {
   try {
    return new ActiveXObject("Microsoft.XMLHTTP");
   } catch(e1) { return null; }
  }
 } else if (window.XMLHttpRequest) {
  return new XMLHttpRequest();
 } else {
  return null;
 }
}
var httpRequest = null;

function sendRequest(url, params, callback, method) {
 httpRequest = getXMLHttpRequest();
 var httpMethod = method ? method : 'GET';
 if (httpMethod != 'GET' && httpMethod != 'POST') {
  httpMethod = 'GET';
 }
 var httpParams = (params == null || params == '') ? null : params;
 var httpUrl = url;
 if (httpMethod == 'GET' && httpParams != null) {
  httpUrl = httpUrl + "?" + httpParams;
 }
 httpRequest.open(httpMethod, httpUrl, true);
 httpRequest.setRequestHeader(
  'Content-Type', 'application/x-www-form-urlencoded');
 httpRequest.onreadystatechange = callback;  //변환작업이 다끝났으면 callback로 넘어간다.
 httpRequest.send(httpMethod == 'POST' ? httpParams : null);    //method가 post 이면 httpParams를 아니면 null을 리턴한다.
}
---------------------------------------------------------------------------------------------------------
사용할 페이지에서
<script type="text/javascript" src="httpRequest.js"></script>
선언하고 사용하면 된다.