Flutter json


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_runnerjson_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 클래스의 fromJsontoJson 메서드가 자동으로 구현됩니다.

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 데이터를 처리, 파싱, 직렬화하는 작업을 더 간단하고 효율적으로 수행할 수 있습니다. 이 방법은 특히 대규모 프로젝트에서 유용합니다.


Leave a Reply

Your email address will not be published. Required fields are marked *