π Today I Learned 21νμ°¨ - λ°μ΄ν° ν΅μ κΈ°μ΄μ JSON π‘
μλ νμΈμ! μ€λμ λ°μ΄ν° ν΅μ μ κΈ°μ΄μ JSON νμμ λν΄ νμ΅νμ΅λλ€. μλ‘ λ€λ₯Έ μΈμ΄λ μμ€ν κ°μ λ°μ΄ν°λ₯Ό μ£Όκ³ λ°κΈ° μν νμ€ νμμΈ JSONμ κ°λ κ³Ό Dartμμμ νμ© λ°©λ²μ λ°°μ μ΄μ!
π― νμ΅ λͺ©ν
- JSON νμμ κ°λ κ³Ό ꡬ쑰 μ΄ν΄νκΈ°
- μ§λ ¬νμ μμ§λ ¬νμ κ°λ μ΅νκΈ°
- Dartμμ
jsonEncodeμjsonDecodeνμ©νκΈ° - κ°μ²΄μ JSON λ¬Έμμ΄ κ° λ³ν ꡬννκΈ°
- 볡μ‘ν μ€μ²© ꡬ쑰μ JSON λ€λ£¨κΈ°
π μ£Όμ λ΄μ©
β JSONμ΄λ?
JSON (JavaScript Object Notation) μ μλ‘ λ€λ₯Έ μΈμ΄λ μμ€ν κ° λ°μ΄ν°λ₯Ό μ£Όκ³ λ°κΈ° μν κ²½λ λ°μ΄ν° κ΅ν νμμ λλ€.
π‘ μ JSONμ μ¬μ©νλμ?: Dart κ°μ²΄λ₯Ό λ€λ₯Έ μΈμ΄ μλ²(μ: Java, Python)λ‘ μ λ¬νλ €λ©΄ νμ€νλ νμμ΄ νμν©λλ€. JSONμ μΈμ΄μ λ 립μ μ΄κ³ μ¬λμ΄ μ½κΈ° μ¬μ΄ ν μ€νΈ νμμ΄κΈ° λλ¬Έμ λ리 μ¬μ©λ©λλ€!
π JSON κΈ°λ³Έ κ·μΉ
| κ΅¬μ± μμ | κ·μΉ | μμ |
|---|---|---|
| Key | λ°λμ λ¬Έμμ΄ (ν°λ°μ΄ν) | "name", "age" |
| Value | 6κ°μ§ νμ κ°λ₯ | μλ μ°Έμ‘° |
| ꡬ쑰 | μ€κ΄νΈ {} λ‘ κ°μΈκΈ° |
{"key": "value"} |
π¨ JSON Value νμ
- String (λ¬Έμμ΄):
"μ€μꡬ" - Number (μ«μ):
7,3.14 - Boolean (λΆλ¦°):
true,false - Array (λ°°μ΄):
["μΌκ²Ήμ΄", "μ°μ΄", "κ³ κ΅¬λ§"] - Object (κ°μ²΄):
{"mobile": "010-0000-0000"} - null:
null
π» JSON μμ
{
"name": "μ€μꡬ",
"age": 7,
"isMale": true,
"favorite_foods": ["μΌκ²Ήμ΄", "μ°μ΄", "κ³ κ΅¬λ§"],
"dislike_foods": [],
"contact": {
"mobile": "010-0000-0000",
"email": null
}
}
β‘ Dartμμμ JSON νμ©
π μ§λ ¬νμ μμ§λ ¬ν
λ°μ΄ν°λ₯Ό μ£Όκ³ λ°μ λλ JSON νμμ StringμΌλ‘ λ³ννμ¬ μ μ‘ν©λλ€.
βββββββββββββββββββββββββββββββββββββββ
β μ§λ ¬ν (Serialization) β
β Dart κ°μ²΄ β Map β JSON String β
β jsonEncode() μ¬μ© β
βββββββββββββββββββββββββββββββββββββββ
β¬οΈ λ€νΈμν¬ μ μ‘
βββββββββββββββββββββββββββββββββββββββ
β μμ§λ ¬ν (Deserialization) β
β JSON String β Map β Dart κ°μ²΄ β
β jsonDecode() μ¬μ© β
βββββββββββββββββββββββββββββββββββββββ
π‘ μ Mapμ κ±°μΉλμ?: κ°μ²΄λ₯Ό λ°λ‘ λ¬Έμμ΄λ‘ λ³ννλ©΄ 볡μ‘νκ³ μ€λ₯κ° λ°μνκΈ° μ½μ΅λλ€.
Mapμ JSONμ ꡬ쑰μ μΌμΉνκΈ° λλ¬Έμ μ€κ° λ¨κ³λ‘ μ¬μ©νλ©΄ μμ νκ² λ³νν μ μμ΄μ!
π νμ λ©μλ
| λ©μλ | μ©λ | λ³ν |
|---|---|---|
toJson() |
κ°μ²΄ β Map | μ§λ ¬ν μ μ¬μ© |
fromJson() |
Map β κ°μ²΄ | μμ§λ ¬ν μ μ¬μ© |
jsonEncode() |
Map β String | dart:convert μ 곡 |
jsonDecode() |
String β Map | dart:convert μ 곡 |
π» μ€μ΅ λ° μμ
π° κΈ°λ³Έ μμ : κ°λ¨ν Human ν΄λμ€
import 'dart:convert';
// π― μ§λ ¬ν: κ°μ²΄λ₯Ό JSON ννμ λ¬Έμμ΄λ‘ λ³ν
// - κ³Όμ : κ°μ²΄ β Map (toJson) β String (jsonEncode)
// π― μμ§λ ¬ν: JSON ννμ λ¬Έμμ΄μ κ°μ²΄λ‘ λ³ν
// - κ³Όμ : String β Map (jsonDecode) β κ°μ²΄ (fromJson)
void main() {
// β
Step 1: JSON λ¬Έμμ΄ μ€λΉ
String easyJson = """
{
"name": "μ€μꡬ",
"age": 7,
"isMale": true
}
""";
// β
Step 2: μμ§λ ¬ν (String β Map)
var decodedData = jsonDecode(easyJson);
// β
Step 3: Mapμ κ°μ²΄λ‘ λ³ν
Human human = Human.fromJson(decodedData);
// β
Step 4: κ°μ²΄λ₯Ό λ€μ MapμΌλ‘ λ³ννμ¬ μΆλ ₯
print(human.toJson());
// μΆλ ₯: {name: μ€μꡬ, age: 7, isMale: true}
}
// π¦ Human ν΄λμ€ μ μ
class Human {
String name;
int age;
bool isMale;
// μΌλ° μμ±μ
Human({
required this.name,
required this.age,
required this.isMale,
});
// π§ fromJson: Map β κ°μ²΄ λ³νμ© named μμ±μ
Human.fromJson(Map<String, dynamic> map)
: this(
name: map['name'],
age: map['age'],
isMale: map['isMale'],
);
// π§ toJson: κ°μ²΄ β Map λ³νμ© λ©μλ
Map<String, dynamic> toJson() {
return {
"name": name,
"age": age,
"isMale": isMale,
};
}
}
π κ³ κΈ μμ : μ€μ²© ꡬ쑰 λ€λ£¨κΈ°
볡μ‘ν JSON ꡬ쑰(λ°°μ΄, μ€μ²© κ°μ²΄)λ₯Ό λ€λ£¨λ λ°©λ²μ λλ€.
void main() {
// π₯ 볡μ‘ν JSON: λ°°μ΄κ³Ό μ€μ²© κ°μ²΄ ν¬ν¨
String hardJson = """
{
"name": "μ€μꡬ",
"age": 7,
"isMale": true,
"favorite_foods": ["μΌκ²Ήμ΄", "μ°μ΄", "κ³ κ΅¬λ§"],
"contact": {
"mobile": "010-0000-0000",
"email": null
}
}
""";
// β
μμ§λ ¬ν: String β Map β κ°μ²΄
var decodedData2 = jsonDecode(hardJson);
HumanAdvanced humanAdvanced = HumanAdvanced.fromJson(decodedData2);
// β
μΆλ ₯ νμΈ
print(humanAdvanced.toJson());
print(humanAdvanced.contact.toJson());
}
// π¦ HumanAdvanced ν΄λμ€: 볡μ‘ν ꡬ쑰
class HumanAdvanced {
String name;
int age;
bool isMale;
List<String> favoriteFoods; // π λ°°μ΄ νμ
Contact contact; // π¦ μ€μ²©λ κ°μ²΄ νμ
HumanAdvanced({
required this.name,
required this.age,
required this.isMale,
required this.favoriteFoods,
required this.contact,
});
// π§ κ°μ²΄ β Map λ³ν
Map<String, dynamic> toJson() {
return {
"name": name,
"age": age,
"isMale": isMale,
"favorite_foods": favoriteFoods,
"contact": contact.toJson(), // β οΈ μ€μ²© κ°μ²΄λ toJson() νΈμΆ!
};
}
// π§ Map β κ°μ²΄ λ³ν
HumanAdvanced.fromJson(Map<String, dynamic> map)
: this(
name: map['name'],
age: map['age'],
isMale: map['isMale'],
// β‘ λ°°μ΄ λ³ν: List<dynamic>μ List<String>μΌλ‘
favoriteFoods: List<String>.from(map['favorite_foods']),
// β‘ μ€μ²© κ°μ²΄ λ³ν: Contact.fromJson() μ¬μ©
contact: Contact.fromJson(map['contact']),
);
}
// π¦ Contact ν΄λμ€: μ°λ½μ² μ 보
class Contact {
String mobile;
String? email; // nullable νμ
Contact({
required this.mobile,
this.email,
});
// π§ κ°μ²΄ β Map λ³ν
Map<String, dynamic> toJson() {
return {
"mobile": mobile,
"email": email, // β
μμ λ¨: "age" β "email"
};
}
// π§ Map β κ°μ²΄ λ³ν
Contact.fromJson(Map<String, dynamic> map)
: this(
mobile: map["mobile"],
email: map["email"], // β
μμ λ¨: "age" β "email"
);
}
π¨ μ£Όμ: μλ³Έ μ½λμμ
Contactν΄λμ€μtoJson()κ³ΌfromJson()μμ"age"λ‘ μλͺ» μμ±λ λΆλΆμ"email"λ‘ μμ νμ΅λλ€!
π ν΅μ¬ ν¬μΈνΈ
λ°°μ΄ λ³ν μ μ£Όμμ¬ν
// β μλͺ»λ λ°©λ²: νμ
λΆμΌμΉ μ€λ₯ λ°μ κ°λ₯
favoriteFoods: map['favorite_foods']
// β
μ¬λ°λ₯Έ λ°©λ²: λͺ
μμ νμ
λ³ν
favoriteFoods: List<String>.from(map['favorite_foods'])
μ€μ²© κ°μ²΄ λ³ν μ μ£Όμμ¬ν
// β μλͺ»λ λ°©λ²: Mapμ κ°μ²΄λ‘ λ³ννμ§ μμ
contact: map['contact']
// β
μ¬λ°λ₯Έ λ°©λ²: fromJson() μμ±μ μ¬μ©
contact: Contact.fromJson(map['contact'])
π μ¬ν νμ΅
π€ μΆκ° νꡬ μ£Όμ
- JSON ν¨ν€μ§:
json_serializableμ μ¬μ©ν μλ μ½λ μμ± - Null Safety: nullable νλ μ²λ¦¬ λ°©λ²
- μλ¬ νΈλ€λ§: JSON νμ± μ μμΈ μ²λ¦¬
- λ€νΈμν¬ ν΅μ : HTTP μμ²κ³Ό JSON μ°λ
- 볡μ‘ν ꡬ쑰: λ€μ€ μ€μ²© κ°μ²΄μ λ°°μ΄ λ€λ£¨κΈ°
π λ§λ¬΄λ¦¬
β μ€λ λ°°μ΄ κ²
- JSON κ°λ : μΈμ΄ λ 립μ μΈ λ°μ΄ν° κ΅ν νμμΌλ‘, key-value ꡬ쑰λ₯Ό κ°μ§
- μ§λ ¬ν: Dart κ°μ²΄λ₯Ό
toJson()βjsonEncode()λ‘ JSON λ¬Έμμ΄λ‘ λ³ν - μμ§λ ¬ν: JSON λ¬Έμμ΄μ
jsonDecode()βfromJson()μΌλ‘ Dart κ°μ²΄λ‘ λ³ν - λ°°μ΄ λ³ν:
List<T>.from()λ©μλλ‘ λͺ μμ νμ λ³ν - μ€μ²© κ°μ²΄: κ° ν΄λμ€μ
toJson()/fromJson()ꡬν νμ - μ€μ΅ κ²°κ³Ό: κΈ°λ³Έ ꡬ쑰μ 볡μ‘ν μ€μ²© ꡬ쑰 λͺ¨λ μ±κ³΅μ μΌλ‘ λ³ν
π λ€μ κ³ν
- JSON μλ μμ±:
json_serializableν¨ν€μ§λ₯Ό νμ©ν 보μΌλ¬νλ μ΄νΈ μ½λ μλν - HTTP ν΅μ :
httpν¨ν€μ§λ₯Ό μ¬μ©ν μ€μ API ν΅μ ꡬν - μλ¬ μ²λ¦¬:
try-catchλ₯Ό νμ©ν μμ ν JSON νμ± - μν κ΄λ¦¬: Providerμ JSON λ°μ΄ν° μ°λ
λκΈλ¨κΈ°κΈ°