Jump to content
과거의 기술자료(읽기 전용): https://tech.devgear.co.kr ×
과거의 기술자료(읽기 전용): https://tech.devgear.co.kr

Recommended Posts

이 글에서는 최근 많이 사용되는 JSON에 대해서 알아보고 델파이에서 JSON 데이터를 작성하거나  JSON데이터를 파싱(읽기) 하는 방법등에 대해서 정리해 보았다. 

JSON이란?

  • JavaScript Object Notation의 약자로 데이터를 저장하거나 전송할 때 많이 사용되는 경량의 DATA 교환 형식이다.
  • JSON 표현식은 사람과 기계 모두 이해하기 쉬우며 용량이 작아서, 최근에는 JSON이 XML을 대체해서 데이터 전송 등에 많이 사용한다.
  • JSON은 데이터 포맷일 뿐이며 어떠한 통신 방법도, 프로그래밍 문법도 아닌 단순히 데이터를 표시하는 표현 방법일 뿐이다.

JSON 특징

  • 서버와 클라이언트 간의 교류에서 일반적으로 많이 사용된다.
  • 다른 프로그래밍 언어를 이용해서도 쉽게 만들 수 있다.
  • 특정 언어에 종속되지 않으며, 대부분의 프로그래밍 언어에서 JSON 포맷의 데이터를 핸들링 할 수 있는 라이브러리, 클래스들을 제공한다.

JSON 문법

  • JSON 형식은 key/value가 존재할 수 있으며 key값이나 문자열은 항상 쌍 따옴표를 이용하여 표기한다.
  • 개체, 배열 등의 표기를 사용할 수 있다.
  • JSON형식에서는 null, number, string, array, object, boolean을 사용할 수 있다.

image.png

JSON 형식

image.png

  •  name-value형식의 쌍
  •  값들의 순서화된 리스트 형식

델파이에서 사용되는 JSON 클래스들

아래 표에 표시된 JSON 데이터를 표현하기 위한  클래스들은 system.json에 정의 되어 있다. (TJSONReader, TJSONWriter 클래스는 뒤에서  설명)

JSON_CLASS.png

 

JSON  데이터 작성(쓰기)

아래 화면과 동일한 JSON 데이터를 작성하기 위해  각각 다른 방식으로 구현한 예제이다.

json writer.png

1.      JSON Objects 사용

procedure TForm1.Button1Click(Sender: TObject);
var
    JSONColor  : TJSONObject;
    JSONObject : TJSONObject;
    JSONArray  : TJSONArray;
begin
   try
     JSONColor := TJSONObject.Create;
     JSONColor.AddPair('name', 'red');
     JSONColor.AddPair('hex', '#f00');
     JSONArray := TJSONArray.Create;
     JSONArray.Add(JSONColor);
     JSONObject := TJSONObject.Create;
     JSONObject.AddPair('colors', JSONArray);
     Memo1.Text := JSONObject.ToString;
   finally
     JSONObject.Free;
    end;
end;

2.      TJSonWriter  사용

  •  TJSONWriter           :  JSON 데이터를 직렬화하는 논리를 제공하는 기본 클래스.

  • TJsonTextWriter   :  JSON 콘텐츠를 작성하기 위해 TJsonWriter에서 확장된 클래스이다. TJsonTextWriter 는 잘못된 JSON에 대한 오류 검사를 제공한다.
  • TStringWriter           문자열에 쓰는 TTextWriter를 구현한다. 작성 중인 문자열은 TStringBuilder 인스턴스를 사용하여 작성된다. 

 

       JSON 데이터를 작성하려면:

  • 지정된 텍스트 작성기(TextWriter)에 데이터를 쓰는 JSONWriter를 작성한다.
  • JSON 토큰이 생성될 적절한 Writer 메소드을 순차적으로 호출한다. 예를 들어 WriteStartObject를 호출하여 JSON 의 오브젝트의 시작 부분을 쓴다.

 

procedure TForm1.Button2Click(Sender: TObject);
var
  writer: TJsonWriter;
  StringWriter: TStringWriter;
begin
  try
    StringWriter := TStringWriter.Create;
    Writer := TJsonTextWriter.Create( StringWriter );

    Writer.WriteStartObject;
    Writer.WritePropertyName('colors');
    Writer.WriteStartArray;
    Writer.WriteStartObject;
    Writer.WritePropertyName('name');
    Writer.WriteValue('red');
    Writer.WritePropertyName('hex');
    Writer.WriteValue('#f00');
    Writer.WriteEndObject;
    Writer.WriteEndArray;
    Writer.WriteEndObject;
    memo2.Text := Stringwriter.ToString;
  finally
     StringWriter.Free;
     Writer.Free;
  end;
end;

3.      TJSONObjectBuilder 사용

  • TJSONObjectBuilder  JSON 오브젝트를 작성하기 위한 다양한 인터페이스를 제공하는 JSONWriter 래퍼 클래스.
  • TJsonTextWriter는 다음과 같은 몇 가지 추가 기능도 제공한다. 포맷 지정은 JSON 텍스트의 형식을 지정하는 방법을 나타낸다. 들여쓰기로 설정하면 결과는 들여쓰기가 있는 읽기 쉬운 JSON 데이터가 된다.

 

procedure TForm1.Button3Click(Sender: TObject);
var
  Builder : TJSONObjectBuilder;
  writer: TJsontextWriter;
  StringWriter: TStringWriter;
  StringBuilder: TStringBuilder;
begin
  try
  StringBuilder := TStringBuilder.Create;
  StringWriter := TStringWriter.Create(StringBuilder);
  Writer := TJsonTextWriter.Create(StringWriter);
  Writer.Formatting := TJsonFormatting.Indented;
  Builder := TJSONObjectBuilder.Create(Writer);
  Builder
    .BeginObject
      .BeginArray('colors')
        .BeginObject
          .Add('name', 'red')
          .Add('hex', '#f00')
        .EndObject
    .EndArray
  .EndObject;
  memo3.Text := Stringbuilder.tostring;
  finally
    Builder.Free;
    writer.Free;
    StringWriter.Free;
    StringBuilder.Free;
  end;
end;

 

  • 그 외의 방법으로 Firedac 컴포넌트인 TFDBatchMove, TFDBatchMoveJsonWriter를 사용하여 텍스트(TFDBatchMoveTextReader 컴포넌트 사용), 데이터셋(TFDBatchMoveDataSetReader 컴포넌트 사용)을 Json 데이터로 생성할 수 있다.
  • 아래 샘플에서는 C:\Users\Public\Documents\Embarcadero\Studio\22.0\Samples\Data 폴더에 있는 xml 데이터를 데이터셋에 로드하여 사용하였음(* 데이터베이스 사용하지 않고 테스트 할 수 있음)
  • TFDBatchMove를 이용한 샘플 :  JSON_BatchMove.zip

 json_batchmove.png

 

JSON 파싱(읽기)

위에서 작성한 JSON  데이터를 아래 화면과 같이 다른 방법을 사용하여 파싱하는 예이다.

json reader.png

1.      JSON Objects 사용

procedure TForm1.Button4Click(Sender: TObject);
var
  JSONValue : TJSONvalue;
begin
  JSONValue := TJSONObject.ParseJSONValue('{"colors":[{"name":"red", "hex":"#f00"}]}');
  try
    Memo4.Lines.Add('READER:');
    if JSONValue is TJSONArray then
  //...
    else if JSONVAlue is TJSONObject then
     Memo4.Lines.Add('colors');
     Memo4.Lines.Add('name: '+ JSONValue.GetValue<string>('colors[0].name'));
     Memo4.Lines.Add('hex: '+ JSONValue.GetValue<string>('colors[0].hex'));
  finally
     JSONVAlue.Free;
  end;
end;

2.      TJSonReader 사용 

  •  TJSONReader         : JSON 또는 유사한 형식의 직렬화된 데이터를 읽을 수 있는 기본 클래스. 이 클래스를 사용하기 위해서는 uses절에 System.JSON.Readers을 추가해야 한다.
  •  TJsonTextReader  JSON 형식으로 직렬화된 데이터를 읽는 클래스.
  •  TStringReader        : 문자열에 대한 리더 클래스

      데이터를 읽으려면:

  • 텍스트 리더에서 데이터를 읽는 JSONReader 를 생성한다.
  • 리더가 입력 데이터의 첫 번째 JSON 토큰으로 이동하도록 Read를 호출한다.
  • TokenType은 토큰의 유형을 나타낸다. 또한 IsPrimitiveToken, IsStartToken 또는 IsEndToken을 사용하여 토큰 유형이 특정 토큰 유형 집합에 속하는지 여부를 확인할 수 있다.
  • Value 속성은 토큰 값에 대한 액세스를 제공한다.  예를 들어 TokenType이 PropertyName이면 Value.AsString을 호출하여 속성 이름에 액세스 한다.
  • CurrentState는 리더 상태를 나타낸다.
  • LineNumber 및 LinePosition은 리더가 있는 입력 데이터 내 위치를 나타낸다.
procedure TForm1.Button5Click(Sender: TObject);
var
  LStringReader : TStringReader;
  LJsonTextReader : TJsonTextReader;
begin
 LStringReader := TStringReader.Create('{"colors":[{"name":"red", "hex":"#f00"}]}');
 LJsonTextReader:= TJsonTextReader.Create(LStringReader);
try
  while LJsonTextReader.read do
    case LJsonTextReader.TokenType of
      TJsonToken.PropertyName:
      Memo5.Lines.Add(LJsonTextReader.Value.AsString);
	  TJsonToken.String:
      Memo5.Lines[Memo5.Lines.Count-1] := Memo5.Lines[Memo5.Lines.Count-1] + ': ' +LJsonTextReader.Value.AsString;
    end;
finally
    LStringReader.free;
    LJsonTextReader.Free;
end;
end;

3.   TJONIterator 사용

  JSON 리더가 제공하는 콘텐츠를 반복할 수 있다. lterrator는 JSON 리더와 유사하지만 몇 가지 추가 기능을 제공하고 약간 다르게 작동한다.

  예를 들어:

  • Lterator는 모든 토큰을 통과할 필요가 없다. 특정 배열 또는 개체 항목으로 이동하거나, 배열 및 개체의 일부를 건너뛰거나, 전체 배열 및 개체를 건너뛸 수 있다.
  •  lterrator 배열 또는 개체 값의 토큰에 있으면 해당 값과 일치하는 배열 인덱스 또는 개체 키를 읽을 수 있다. 해당 정보를 별도로 추적할 필요가 없다.
  • terrator는 오브젝트 키에서 멈추지 않는다. 대신 키를 건너뛰고 해당 값의 토큰으로 반복한다. iterator의 Key 속성에서 Value 토큰의 키를 읽을 수 있다.

  JSONReader 의 내용을 반복하려면:

  • JSON Reader에서 데이터를 읽는 JSON Lterator를 생성한다.
  •  Next메소드를 호출하면 리더가 입력 데이터의 첫 번째 JSON 토큰으로 이동한다.
  • 유형은 토큰의 유형을 나타냅니다.
  • 배열을 반복하는 경우 인덱스를 사용하여 현재 토큰의 인덱스를 가져온다. 오브젝트를 반복하는 경우 Key를 사용하여 현재 토큰의 키를 가져온다.
  • Lterator의 값 속성 중 하나를 사용하여 현재 토큰의 값에 액세스한다. 예를 들어 유형이 부울이면 AsBoolean을 호출하여 현재 토큰의 부울 값에 액세스한다.
  • Next를 계속 호출하여 입력 데이터의 모든 JSON 토큰을 살펴본다. Next는 입력 데이터의 끝에 도달하면 False를 반환한다.
  • Recurse(되감기)를 사용하여 Lterator를 입력 데이터의 시작 부분으로 다시 이동할 수 있다.

 

procedure TForm1.Button6Click(Sender: TObject);
var
  LStringReader : TStringReader;
  LJsonTextReader : TJsonTextReader;
  LIterator : TJSONIterator;
begin
  LStringReader := TStringReader.Create('{"colors":[{"name":"red", "hex":"#f00"}]}');
  LJsonTextReader := TJsonTextReader.Create(LStringReader);
  LIterator := TJSONIterator.Create(LJsonTextReader);
 try
    LIterator.Next;
    Memo6.Lines.Add(LIterator.Key);
    LIterator.Recurse;
    LIterator.Next;
    LIterator.Recurse;
    LIterator.Next;
    Memo6.Lines.Add(LIterator.Key +': '+ LIterator.AsString);
    LIterator.Next;
    Memo6.Lines.Add(LIterator.Key +': '+ LIterator.AsString);
 finally
    LStringReader.Free;
    LJsonTextReader.Free;
    LIterator.Free;
  end;
end;

  샘플 소스  :  JSON_Reader_Writer.zip

 

 

이 댓글 링크
다른 사이트에 공유하기

  • 1 year later...
On 2021. 11. 3. at 오후 5시 5분, 김원경 said:

  JSON Objects 사용

파싱할때 에 기본값을 설정하려면 

(TJSONObject).GetValue<String>('KeyName', 'DefaultValue')

이런식으로 2번째 파라미터에 값을 넣어주시면 됩니다.

간혹 오타나, 누락된 값을 파싱하려고 하면 오류가 발생하니,

JSON 작업시 참고해주세요~

 

※ 수정해야 하는 부분 있으면 댓글이나 쪽지 부탁드립니다!

이 댓글 링크
다른 사이트에 공유하기

이 토의에 참여하세요

지금 바로 의견을 남길 수 있습니다. 그리고 나서 가입해도 됩니다. 이미 회원이라면, 지금 로그인하고 본인 계정으로 의견을 남기세요.

Guest
이 토픽(기고/질문)에 답하기

×   서식있는 텍스트로 붙여넣기.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   이전에 작성한 콘텐츠가 복원되었습니다..   편집창 비우기

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

중요한 정보

이용약관 개인정보보호정책 이용규칙 이 사이트가 더 잘 작동하기 위해 방문자의 컴퓨터에 쿠키가 배치됩니다. 쿠키 설정 변경에서 원하는 설정을 할 수 있습니다. 변경하지 않으면 쿠키를 허용하는 것으로 이해합니다.