Post List

2015년 5월 20일 수요일

web::json::value 사용법 (C++ REST SDK)

* 관련 Posting

 - C++ RESK SDK in Visual Studio 2013 설치 및 offline용 package 파일 (nupkg) 만들기
 - Web Page 의 결과를 std::wstring 로 받아오는 방법 ( C++ REST SDK 사용 )
 - Web Service의 json 결과를 받는 방법 ( C++ REST SDK 사용 )
 - web::json::value 사용법 (C++ REST SDK)


C++ REST SDK ( 코드명 : Casablanca ) 에는 json parser가 내장되어 있습니다.
Web에서 결과를 json 으로 받아온다던지,
아니면 json 으로 저장된 string 으로 부터 parsing을 하면
web::json::value 타입으로 저장됩니다.

web::json::value V; 라고 선언되었으며, 아래의 json 이 저장되었다는 가정하에 설명을 진행하겠습니다.

 [{"class":"com.jolorenz.rest.City","id":1,"cityName":"Munich","countryCode":"DE","dateCreated":"2015-05-19T04:59:07Z","lastUpdated":"2015-05-19T04:59:07Z","postalCode":"81927"},
 {"class":"com.jolorenz.rest.City","id":2,"cityName":"Berlin","countryCode":"DE","dateCreated":"2015-05-19T04:59:07Z","lastUpdated":"2015-05-19T04:59:07Z","postalCode":"10115"}]


1. web::json::value의 상태

  3 가지 상태를 가집니다.
  (다른 상태들이 더 있지만, 일단 3가지만 알아도 사용하는데는 무리가 없습니다.)

  - V.is_array() == true

   다른 json object 들을 가진 상태를 의미 합니다.
   위 json 전체에 해당하는 경우 입니다.

 [{"class":"com.jolorenz.rest.City","id":1,"cityName":"Munich","countryCode":"DE","dateCreated":"2015-05-19T04:59:07Z","lastUpdated":"2015-05-19T04:59:07Z","postalCode":"81927"},
 {"class":"com.jolorenz.rest.City","id":2,"cityName":"Berlin","countryCode":"DE","dateCreated":"2015-05-19T04:59:07Z","lastUpdated":"2015-05-19T04:59:07Z","postalCode":"10115"}]

  - V.is_object() == true

   value 들을 포함한 object 상태를 의미 합니다.
   위 json 에는 총 2개의 json object 가 있습니다.

 [{"class":"com.jolorenz.rest.City","id":1,"cityName":"Munich","countryCode":"DE","dateCreated":"2015-05-19T04:59:07Z","lastUpdated":"2015-05-19T04:59:07Z","postalCode":"81927"},
 {"class":"com.jolorenz.rest.City","id":2,"cityName":"Berlin","countryCode":"DE","dateCreated":"2015-05-19T04:59:07Z","lastUpdated":"2015-05-19T04:59:07Z","postalCode":"10115"}]

  - 직접적으로 값을 가지는 상태

    V.is_string() == true
    V.is_integer() == true

    V.is_double() == true



    V.is_boolean() == true
    등등 ...

    key 와 value 의 쌍으로 값을 가지는 상태를 의미합니다.
    위 json의 각각의 object 는 7개의 값을 가지고 있습니다.

 [{"class":"com.jolorenz.rest.City","id":1,"cityName":"Munich","countryCode":"DE","dateCreated":"2015-05-19T04:59:07Z","lastUpdated":"2015-05-19T04:59:07Z","postalCode":"81927"},
 {"class":"com.jolorenz.rest.City","id":2,"cityName":"Berlin","countryCode":"DE","dateCreated":"2015-05-19T04:59:07Z","lastUpdated":"2015-05-19T04:59:07Z","postalCode":"10115"}]


2. array 상태에서 json object로 분리

   web::json::value를 as_array() 함수를 이용하여 web::json::array로 만든 뒤,
   ranged-for 나 iterator를 이용하여 각각의 web::json::value로 분리하시면 됩니다.

if (V.is_array())
{
    web::json::array A = V.as_array();

    // ranged-for
    for (auto O : A) // auto = web::json::value
    {
        if (O.is_object())
        {
            // O 작업
        }
    }

    // const iterator 사용
    for (auto IT = A.cbegin(); IT != A.cend(); IT++)
    {
        if (IT->is_object())
        {
            // *IT 작업
        }
    }
}


3. json object 에서 각각의 값으로 분리

  .at(key명칭) 함수를 이용하여 분리가 가능합니다.
  object 내에 어떤 key 들이 있는지를 찾는 함수라던지,
  모든 key , value 를 추출하는 iterator 같은 것은 없었습니다.
  이 기능이 생기면 정말 편리하겠네요.
  그렇게 추출한 타입 또한 web::json::value입니다.
  여기서 구체적인 값을 추출하는 방법은 as_integer()as_string() 등의 함수를 이용하면 됩니다.

web::json::value jId = V.at(U("id"));
if (jId.is_integer())
{
    int nId = jId.as_integer();
}

web::json::value jClass = V.at(U("class"));
if (jClass.is_string())
{
    std::wstring sClass = jClass.as_string();
}

여기까지 보시면 이제 json 을 읽어와서 그 값들을 읽는 것은 모두 해결이 됩니다.
지금부터는 json 에 원하는 값을 넣어서 json 개체를 생성하는 방법을 살펴보겠습니다.


4. json object에 값을 입력하는 방법

  index operator [] 를 이용하여 값의 수정 또는 새로운 값의 입력이 가능합니다.
  값을 넣을 때는 web::json::value내에 static으로 정의된 함수들을 이용합니다.
  web::json::value::string(),   web::json::value::number()등 함수의 return 타입은 모두 web::json::value입니다.
  그러므로 직접 구체적 값을 가진 web::json::value를 대입해도 됩니다.

V[U("class")] = web::json::value::string(U("devstory.lunastar"));
V[U("id")] = web::json::value::number(770726);


5. json object 들을 array로 묶는 방법

  web::json::value::array()라는 static함수에 std::vector<web::json::value>를 인자로 전달하면 됩니다.
  물론 std::vector에 들어 있는 각각의 web::json::value를 포함한 array로 생성됩니다.
  참고로 web::json::value::array() 의 return 타입은 web::json::value입니다.

std::vector<web::json::value> VJ;
// VJ.emplace_back() web::json::value 들을 넣는 Code ...
web::json::value V = web::json::value::array(VJ);


6. json object를 string 으로 출력하는 방법

  .serialize() 함수를 이용하면 std::wstring 타입으로 return 됩니다.
  예전 버전에는 .to_string() 였는지 해당 함수도 존재하지만 사용시 오류를 내면서
  .serialize()를 사용하라고 메세지를 출력합니다.

위에 설명한 방법들을 이용하여 json 파싱을 좀 더 편리하게 사용하도록 class를 하나 생성하였습니다.
위 설명들을 다 이해하신다면 아래 code를 이해하시는데 어려움은 없을꺼에요.

참고로 Web Service 는 아래 Posting을 참조하여 Grails 를 이용하여 간단하게 작성하였습니다.

https://jolorenz.wordpress.com/2014/02/28/create-a-restservice-api-with-grails-2-3-x-in-15-minutes/

Web Service에서 json 으로 결과를 받아오는 방법은 아래 Posting을 참조하시면 됩니다.

http://devluna.blogspot.kr/2015/05/web-service-json-c-rest-sdk.html

* JsonObject.h

* JsonObject.cpp

* example_JsonObject.cpp