Flutter JSON 데이터처리, 파싱, 직렬화
Flutter에서 JSON 데이터를 처리, 파싱, 직렬화하는 방법은 여러 가지가 있습니다. 여기서는 기본적인 방법부터 JSON 데이터를 모델 클래스로 변환하는 방법, 그리고 json_serializable
패키지를 사용하는 방법까지 다양한 접근 방식을 설명하겠습니다.
1. JSON 데이터 처리와 파싱
JSON 데이터 가져오기
먼저, HTTP 요청을 통해 JSON 데이터를 가져오는 예제를 보겠습니다. 이를 위해 http
패키지를 사용합니다.
dependencies:
flutter:
sdk: flutter
http: ^0.14.0
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
late Future<Post> post;
@override
void initState() {
super.initState();
post = fetchPost();
}
Future<Post> fetchPost() async {
final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/1'));
if (response.statusCode == 200) {
return Post.fromJson(json.decode(response.body));
} else {
throw Exception('Failed to load post');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('JSON Parsing Example')),
body: Center(
child: FutureBuilder<Post>(
future: post,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data!.title);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return CircularProgressIndicator();
},
),
),
);
}
}
class Post {
final int userId;
final int id;
final String title;
final String body;
Post({
required this.userId,
required this.id,
required this.title,
required this.body,
});
factory Post.fromJson(Map<String, dynamic> json) {
return Post(
userId: json['userId'],
id: json['id'],
title: json['title'],
body: json['body'],
);
}
}
2. JSON 데이터를 모델 클래스로 변환
모델 클래스를 만들어 JSON 데이터를 파싱하고 직렬화할 수 있습니다. 위 예제에서 이미 Post
모델 클래스를 만들었습니다. 이 클래스에는 JSON 데이터를 Dart 객체로 변환하는 fromJson
메서드가 있습니다.
직렬화
Dart 객체를 JSON으로 변환하는 방법은 다음과 같습니다.
Map<String, dynamic> toJson() => {
'userId': userId,
'id': id,
'title': title,
'body': body,
};
객체를 JSON 문자열로 변환할 때는 jsonEncode
함수를 사용합니다.
String postToJson(Post post) {
final Map<String, dynamic> postData = post.toJson();
return json.encode(postData);
}
3. json_serializable
패키지를 사용한 자동 생성
json_serializable
패키지를 사용하면 모델 클래스의 JSON 변환 코드를 자동으로 생성할 수 있습니다. 이 패키지를 사용하려면 build_runner
와 json_serializable
패키지를 pubspec.yaml
파일에 추가해야 합니다.
dependencies:
flutter:
sdk: flutter
json_annotation: ^4.4.0
dev_dependencies:
build_runner: ^2.1.0
json_serializable: ^6.0.0
모델 클래스 생성
먼저 모델 클래스를 작성합니다.
import 'package:json_annotation/json_annotation.dart';
part 'post.g.dart';
@JsonSerializable()
class Post {
final int userId;
final int id;
final String title;
final String body;
Post({
required this.userId,
required this.id,
required this.title,
required this.body,
});
factory Post.fromJson(Map<String, dynamic> json) => _$PostFromJson(json);
Map<String, dynamic> toJson() => _$PostToJson(this);
}
코드 생성
터미널에서 다음 명령어를 실행하여 JSON 직렬화 코드를 생성합니다.
flutter pub run build_runner build
이 명령어를 실행하면 post.g.dart
파일이 생성되며, Post
클래스의 fromJson
및 toJson
메서드가 자동으로 구현됩니다.
4. 전체 예제
위에서 설명한 모든 내용을 종합하여 json_serializable
을 사용한 전체 예제를 작성해 보겠습니다.
main.dart
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'post.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
late Future<Post> post;
@override
void initState() {
super.initState();
post = fetchPost();
}
Future<Post> fetchPost() async {
final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/1'));
if (response.statusCode == 200) {
return Post.fromJson(json.decode(response.body));
} else {
throw Exception('Failed to load post');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('JSON Parsing Example')),
body: Center(
child: FutureBuilder<Post>(
future: post,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data!.title);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return CircularProgressIndicator();
},
),
),
);
}
}
post.dart
import 'package:json_annotation/json_annotation.dart';
part 'post.g.dart';
@JsonSerializable()
class Post {
final int userId;
final int id;
final String title;
final String body;
Post({
required this.userId,
required this.id,
required this.title,
required this.body,
});
factory Post.fromJson(Map<String, dynamic> json) => _$PostFromJson(json);
Map<String, dynamic> toJson() => _$PostToJson(this);
}
이와 같이 json_serializable
패키지를 사용하면 JSON 데이터를 처리, 파싱, 직렬화하는 작업을 더 간단하고 효율적으로 수행할 수 있습니다. 이 방법은 특히 대규모 프로젝트에서 유용합니다.