flutter 开发笔记(三):JSON

6 阅读2分钟

严格来说,JSON 处理相关的内容主要与 Dart 语言相关,而不是 Flutter 框架本身。然而,在实际应用开发中,一个应用程序几乎不可避免地需要处理网络请求和数据交互,这使得处理 JSON 数据成为常见的任务。因此,尽管 JSON 处理是 Dart 的功能,但在构建 Flutter 应用时,这项技能同样不可或缺

两种方式处理 JSON

在 Java 中,解析 JSON 字符串通常有两种方法:一种是使用自带的 JSONObject 类,另一种则是使用如 GSON 等第三方库。前者可以直接解析 JSON 数据,而后者则需要你定义一个数据类来表示 JSON 数据结构,然后将 JSON 数据解析为这些数据类的实例

两种方法各有优缺点。使用 JSONObject 类的方法简单方便,适用于快速开发和小型项目,但缺点是代码不够结构化和难以维护。相反,使用 GSON 等库的方法则要求定义数据类,尽管增加了初始开发工作量,但在大型项目中提供了更好的类型安全性和可维护性

类似的,Dart 也提供了两种处理 JSON 数据的方法,当然优缺点也相同

使用 Map<String, dynamic> 解析 JSON 数据

这种方法类似于 Java 中的 JSONObject,不需要定义额外的数据模型类。适用于快速解析和处理 JSON 数据,但缺乏类型安全和结构化

import 'dart:convert';

void main() {
  // 示例 JSON 字符串
  String jsonString = '''
  {
    "id": 1,
    "name": "John Doe",
    "isActive": true,
    "address": {
      "street": "123 Main St",
      "city": "Anytown"
    }
  }
  ''';

  // 反序列化:将 JSON 字符串解析为 Dart 对象
  Map<String, dynamic> user = json.decode(jsonString);

  int id = user['id'];
  String name = user['name'];
  bool isActive = user['isActive'];

  Map<String, dynamic> address = user['address'];
  String street = address['street'];
  String city = address['city'];

  print('ID: $id');        // 输出: ID: 1
  print('Name: $name');    // 输出: Name: John Doe
  print('Active: $isActive'); // 输出: Active: true
  print('Street: $street');   // 输出: Street: 123 Main St
  print('City: $city');    // 输出: City: Anytown

  // 序列化:将 Dart 对象转换为 JSON 字符串
  Map<String, dynamic> userToSerialize = {
    'id': id,
    'name': name,
    'isActive': isActive,
    'address': {
      'street': street,
      'city': city,
    }
  };

  String serializedJson = json.encode(userToSerialize);
  print(serializedJson);  // 输出: {"id":1,"name":"John Doe","isActive":true,"address":{"street":"123 Main St","city":"Anytown"}}
}

使用定义的数据类解析 JSON 数据

这种方法要求定义数据类来表示 JSON 数据结构,并使用 fromJsontoJson 方法来解析和生成 JSON 数据。尽管增加了初始开发工作量,但提供了更好的类型安全性和代码可读性,便于维护

不过,定义数据类很方便再次序列化

import 'dart:convert';

class User {
  final int id;
  final String name;
  final bool isActive;
  final Address address;

  User({
    required this.id,
    required this.name,
    required this.isActive,
    required this.address,
  });

  factory User.fromJson(Map<String, dynamic> json) {
    return User(
      id: json['id'],
      name: json['name'],
      isActive: json['isActive'],
      address: Address.fromJson(json['address']),
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'name': name,
      'isActive': isActive,
      'address': address.toJson(),
    };
  }
}

class Address {
  final String street;
  final String city;

  Address({
    required this.street,
    required this.city,
  });

  factory Address.fromJson(Map<String, dynamic> json) {
    return Address(
      street: json['street'],
      city: json['city'],
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'street': street,
      'city': city,
    };
  }
}

void main() {
  // 示例 JSON 字符串
  String jsonString = '''
  {
    "id": 1,
    "name": "John Doe",
    "isActive": true,
    "address": {
      "street": "123 Main St",
      "city": "Anytown"
    }
  }
  ''';

  // 反序列化:将 JSON 字符串解析为 Dart 对象
  Map<String, dynamic> userMap = json.decode(jsonString);
  User user = User.fromJson(userMap);

  // 输出反序列化后的对象
  print('ID: ${user.id}');
  print('Name: ${user.name}');
  print('Active: ${user.isActive}');
  print('Street: ${user.address.street}');
  print('City: ${user.address.city}');

  // 序列化:将 Dart 对象转换为 JSON 字符串
  String jsonStringSerialized = json.encode(user.toJson());
  print(jsonStringSerialized);  // 输出: {"id":1,"name":"John Doe","isActive":true,"address":{"street":"123 Main St","city":"Anytown"}}
}