안녕하세요 개발자 베베입니다.
이번 포스팅에서는 플러터에서 json 데이터를 사용하는 방법에 대해서 알아보도록 하겠습니다.
1. 자료형에 대한 이해
2. json 스트링을 Map<String, dynamic> 자료형으로 변환
3. Map<String, dynamic> 자료형을 객체로 변환
4. 객체를 json 스트링으로 변환
자료형에 대한 이해
플러터, 정확히는 Dart 언어에서 json을 다루기 위해선 먼저, 관련된 자료형에 대한 정리가 필요하다.
첫번째로 json 파일을 파일 입출력을 통해 가져오게 되면 json 데이터는 텍스트 데이터이기 때문에 String 형으로 들어오게 된다. 이 글에서는 파일 입출력을 통해 가져온 json 데이터 스트링을 json 스트링이라고 부르도록 하겠다.
두번째로 Dart에서는 json을 다루기 위해 Map<String, dynamic> 이라는 자료형을 사용한다. json 데이터는 키와 값으로 이루어져있고 키는 반드시 String이며 값은 자료형이 정해져있지 않다. 때문에 Map<String, dynamic> 자료형으로 모든 json 데이터를 다룰 수 있다. 이 글에선 json 자료형이라고 부르겠다.
마지막으로 json 데이터가 들어갈 객체다. json을 사용한다는 것은 결국 데이터를 최종 결과물인 객체로 생성해내는 것이다.
Dart에서 json을 사용한다는 것은 위 세가지를 순서에 맞게 변형시켜주는 것이다.
3가지 종류를 다뤄야하기 때문에 용어를 반드시 숙지하고 사용해야 헷갈리지 않습니다.
json 스트링 : json 텍스트 데이터 (자료형 : String)
json 자료형 : Dart에서 json 데이터를 다루기 위해 사용되는 자료형 (자료형 : Map<String, dynamic>)
json 객체 : json 데이터를 파싱하여 얻은 객체. 사용자가 직접 정의해야함(자료형 : Object)
json 스트링을 json 자료형으로 변환시키기 위해선 첫번째로 json 파일에서 json 스트링을 추출해야 합니다. 이 과정은 파일 입출력에 대한 부분이기 때문에 다음과 같이 추출이 완료되었다고 가정하고 나머지 단계를 진행하겠습니다.
String jsonString = '''
{
"name" : "bebe",
"age" : 26,
"is_man" : true
}
''';
json 스트링을 얻었으니 json 자료형으로 변환할 차례입니다. 이 과정은 고맙게도 dart에서 제공하는 기본 라이브러리 함수를 사용하여 수행할 수 있습니다.
Map<String,dynamic> jsonData = jsonDecode(jsonString);
print(jsonData['name']); // bebe 출력
print(jsonData['age']); // 26 출력
print(jsonData['is_man']); // true 출력
json 스트링을 json 자료형으로 성공적으로 변환시켰으니 이젠 그 값으로 객체를 생성해 볼 차례입니다.
이 과정을 수행하기 위해선 먼저 json 데이터와 매칭되는 객체를 정의해주어야 합니다.
class User{
String name;
int age;
bool isMan;
User({
this.name,
this.age,
this.isMan,
});
}
여기부터 초보자분들은 조금 헷갈리실 수 있는데, 다음 코드처럼 클래스 내부에 팩토리 함수를 이용하여 fromJson이라는 함수를 정의해주어야 합니다.
factory User.fromJson(Map<String, dynamic> jsonData){
return User(
name: jsonData['name'],
age: jsonData['age'],
isMan: jsonData['is_man'],
);
}
이렇게 정의하고 나면 다음처럼 json String을 객체로 변환할 수 있습니다.
Map<String, dynamic> jsonData = jsonDecode(jsonString);
User user = User.fromJson(jsonData); // fromJson 팩토리 함수로 user 객체를 찍어낸다.
여기까지 json 스트링을 객체로 파싱하는 방법에 대한 설명이였습니다.
이제는 반대의 과정에 대해 알아보도록 하겠습니다. 위에서 설명했듯 json 스트링을 객체로 변환할 때에는 json 자료형으로 변환시키는 중간 과정이 필요했습니다. 그러나 반대의 과정은 이 과정이 필요하지 않습니다. 대신 클래스 내부에 toJson이라는 객체 함수를 정의해주어야 하는데, 다음과 같은 형태입니다.
Map<String, dynamic> toJson(){
return {
'name':name,
'age':age,
'is_man':isMan,
};
}
toJson함수는 말 그대로 객체의 정보를 json 자료형으로 반환해주는 함수입니다. Dart 문법에서 Map 자료형은 중괄호로 표현할 수 있는데, 그것을 이용한 코드 작성방법입니다.
Dart에서는 객체를 json 스트링으로 변환해주는 jsonEncode 함수를 제공합니다. 이 때, jsonEncode 함수는 내부에서 객체의 toJson 함수를 호출하여 Map<String, dynamic> 자료형을 얻고, 그 값을 json 스트링으로 반환합니다.
String jsonString = jsonEncode(user);
여기까지 객체를 json 스트링으로 변환하는 방법이였습니다.
여기서 다뤄본 예제의 json 스트링은 구조가 복잡하지 않았습니다. 전부 기본 자료형만 사용되었기 때문이죠. 만약 아래처럼 복잡한 구조의 json 스트링은 어떻게 다루어야 할까요?
String jsonString = '''
{
"name" : "bebe",
"age" : 26,
"is_man" : true,
"friends":[
{
"name":"hong"
},
{
"name":"lee"
}
],
"address":{
"location":"Seoul",
"number":"11654"
}
}
''';
다음 시간에는 배열이 포함된 json 스트링을 다루는 방법, 객체 안에 객체가 있는 json 스트링을 다루는 방법에 대하여 알아보도록 하겠습니다.