Flutter JSON解析插件typed_json的使用

Flutter JSON解析插件typed_json的使用

安装

在你的项目 pubspec.yaml 文件中添加以下依赖:

dependencies:
  typed_json: ^1.0.0

安装依赖:

dart pub get

导入库:

import 'package:typed_json/typed_json.dart';

基本用法

字符串解析

final str = '{"title": "Roadside Picnic", "year": 1972, "inStock": false}';
try {
  final json = Json.parse(str);
} on JsonException catch (e) {
  print(e);
}

将JSON转换为字符串

final unformatted = json.asString();
final formatted = json.asPrettyString();

创建空的JSON

Json nullJson = Json.empty(); // null
Json emptyList = Json.list(); // []
Json emptyObject = Json.object(); // {}

从值创建JSON

Json intJson = Json(1); // 1
Json doubleJson = Json(1.1); // 1.1
Json stringJson = Json("str"); // "str"
Json boolJson = Json(true); // true

写入值

Json json = Json.object();
json["int"].intValue = 1;
json["string"].stringValue = "str";
json["double"].doubleValue = 1.1;
json["double"].numValue = 1.1;
json["bool"].boolValue = true;

读取值

可以这样读取可为空的值:

try {
  int? intVal = json["year"].intValue;
  String? stringVal = json["title"].stringValue;
  double? doubleVal = json["price"].doubleValue;
  num? numValue = json["price"].numValue;
  bool? boolVal = json["inStock"].boolValue;
} on JsonValueException catch (e) {
  print(e.value); // The value of the faulty field
  print(e); // "Unable to parse the value at the/path/to/field"...
}

如果值的类型不正确,将抛出 JsonValueException。允许值为 null

必填值

如果值不能为空,可以使用 *OrException 属性:

try {
  int intVal = json["year"].intOrException;
  String stringVal = json["title"].stringOrException;
  double doubleVal = json["price"].doubleOrException;
  num numValue = json["price"].numOrException;
  bool boolVal = json["inStock"].boolOrException;
} on JsonValueException catch (e) {
  print(e.value); // The value of the faulty field
  print(e); // "Unable to parse the required value at the/path/to/field"...
}

如果值的类型不正确或值为空,将抛出 JsonValueException

创建JSON对象

从字典创建

final json = Json({
    "name": "John",
    "age": 20,
    "contacts": {
      "email": "john@doe.com",
      "phones": ["754-3010"]
    }
  });

手动创建

final json = Json.object();
json["name"].stringValue = "John";
json["age"].intValue = 20;
json["contacts"] = Json.object();
json["contacts"]["email"].stringValue = "john@doe.com";
json["contacts"]["phones"] = Json.list();
json["contacts"]["phones"].list.add(Json("754-3010"));

访问嵌套对象的值

final value = j["root"]["nested"].stringValue;

在上面的例子中,“root” 和 “nested” 键必须不为 null,否则会抛出 JsonException。如果你需要解析可能为 null 的嵌套 JSON,应该显式检查。

final value1 = j["inexisted"]["nested"].stringValue; // JsonException

final value2 = j["inexisted"].isExist 
  ? j["inexisted"]["nested"].stringValue 
  : null; // null

你也可以使用快捷方式。

final value = j["inexisted"].optional["nested"].stringValue; // null

在这个例子中,我们将路径 “inexisted” 标记为“可选”。JSON 解析器将知道 “inexisted” 可能为 null。并且 “nested” 和 “inexisted” 右边的所有键也可以为 null

空检查

你可以检查 JSON 值是否不为 null

final json = Json.empty(); // json with null
print(json != null); // true
print(json.isExist); // false

你可以检查 JSON 对象是否包含给定名称的元素:

final json = Json.object(); // json with {}
print(json.isExist); // true
print(json["key"].isExist); // false

类型检查

你可以检查 JSON 值的运行时类型:

Json("value").isA<String>; // true
Json("value").isNot<int>; // true

你还可以检查 “dynamicValue” 属性的类型:

Json("value").dynamicValue is String; // true
Json("value").dynamicValue is int; // false

处理JSON列表

你可以创建一个 JSON 列表:

final fromAListOfValues = Json(["John", "Jack"]);
final fromAListOfDictionaries = Json([{"name": "John"}, {"name": "Nick"}]);
final fromAListOfJsons = Json([Json("John"), Json("Jack")]);

你可以通过 list 属性访问 JSON 对象的列表:

List<Json> jsonList = json.list;

你可以创建一个空数组并使用 add() 方法填充它:

final json = Json.list(); // []
json.list.add(Json({"item": 1})); // [{"item":1}]
json.list.add(Json({"item": 2})); // [{"item":1}, {"item":2}]

你可以这样修改列表项:

final item1 = Json({"item": 1});
final item2 = Json({"item": 2});

final json = Json([item1]); // [{"item":1}]
json.list.remove(item1); // []
json.list.add(item2); // [{"item":2}]

处理对象列表

class Book {
  final String title;
  final int year;
  final bool inStock;
  final double price;

  Book({this.title, this.year, this.inStock, this.price});
}

final books = [
  Book(title: "Beetle in the Anthill", year: 1979, inStock: true, price: 5.99)
];

// 从对象列表创建JSON
Json listJson = Json.fromObjectList(books, (Book item) {
  var j = Json.object();
  j["title"].stringValue = item.title;
  j["year"].intValue = item.year;
  j["inStock"].boolValue = item.inStock;
  j["price"].doubleValue = item.price;
  return j;
});

// 从JSON创建对象列表
List<Book>? objectList = listJson.toObjectList(
  (j) => Book(
    title: j["title"].stringValue!,
    year: j["year"].intValue!,
    inStock: j["inStock"].boolValue!,
    price: j["price"].doubleValue!,
  ),
);

处理自定义类型

有时你需要在JSON中处理枚举、日期等自定义类型。

enum Status { active, old }

你可以实现 JsonAdapter 来解析自定义类型的值。

class StatusAdapter implements JsonAdapter<Status> {
  @override
  Status? fromJson(Json json) {
    switch (json.stringValue) {
      case "active":
        return Status.active;
      case "old":
        return Status.old;
      default:
        return null;
    }
  }

  @override
  Json toJson(Status? value) {
    if (value == null) {
      return Json.empty();
    }
    switch (value) {
      case Status.active:
        return Json("active");
      case Status.old:
        return Json("old");
      default:
        return Json.empty();
    }
  }
}

现在你可以使用 getset 方法处理具有自定义类型的JSON值。

final valueJson = Json.empty();
valueJson.set(Status.active, StatusAdapter());
Status? valueStatus = valueJson.get(StatusAdapter());

final objectJson = Json.object();
objectJson["key"].set(Status.active, StatusAdapter());
Status? ojectStatus = objectJson["key"].get(StatusAdapter());

如果值不能为空,你可以使用 getRequired 方法。

final valueJson = Json.empty();
valueJson.set(Status.active, StatusAdapter());
Status valueStatus = valueJson.getRequired(StatusAdapter());

如果自定义适配器返回 nullgetRequired 方法将抛出 JsonValueException

try {
  Json("incorrect").getRequired(StatusAdapter());
} on JsonValueException catch (e) {
  print(e.value); // The value of the faulty field
  print(e); // "Unable to parse the required value at the/path/to/field"...
}

更多关于Flutter JSON解析插件typed_json的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter JSON解析插件typed_json的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用typed_json插件进行JSON解析的示例代码。

首先,确保你已经在pubspec.yaml文件中添加了typed_json依赖:

dependencies:
  flutter:
    sdk: flutter
  typed_json: ^3.0.0  # 请检查最新版本号

然后运行flutter pub get来安装依赖。

接下来,假设我们有一个简单的JSON数据结构和对应的Dart类。

示例JSON数据

{
  "name": "John Doe",
  "age": 30,
  "email": "john.doe@example.com"
}

Dart类定义

首先,我们需要定义一个Dart类来表示这个JSON数据结构。

import 'package:typed_json/typed_json.dart';

@TypedJsonSerializable()
class User {
  final String name;
  final int age;
  final String email;

  User({required this.name, required this.age, required this.email});

  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);

  Map<String, dynamic> toJson() => _$UserToJson(this);
}

// 生成代码的命令:flutter pub run build_runner build

使用typed_json生成代码

typed_json依赖于build_runner来生成解析和序列化的代码。在项目根目录下运行以下命令:

flutter pub run build_runner build

这将生成必要的代码文件,比如user.g.dart,其中包含_$UserFromJson_$UserToJson方法。

解析和序列化JSON

下面是如何使用生成的代码来解析和序列化JSON数据的示例:

import 'dart:convert';
import 'package:flutter/material.dart';
import 'user.dart';  // 假设user.dart文件包含上面的User类定义

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Typed JSON Example'),
        ),
        body: Center(
          child: UserScreen(),
        ),
      ),
    );
  }
}

class UserScreen extends StatefulWidget {
  @override
  _UserScreenState createState() => _UserScreenState();
}

class _UserScreenState extends State<UserScreen> {
  late User user;

  @override
  void initState() {
    super.initState();
    // 示例JSON数据
    String jsonData = '''
    {
      "name": "John Doe",
      "age": 30,
      "email": "john.doe@example.com"
    }
    ''';
    
    // 解析JSON数据
    Map<String, dynamic> jsonMap = jsonDecode(jsonData);
    user = User.fromJson(jsonMap);
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text('Name: ${user.name}'),
        Text('Age: ${user.age}'),
        Text('Email: ${user.email}'),
        ElevatedButton(
          onPressed: () {
            // 序列化对象回JSON
            String jsonString = jsonEncode(user.toJson());
            print('Serialized JSON: $jsonString');
          },
          child: Text('Serialize to JSON'),
        ),
      ],
    );
  }
}

运行项目

确保所有文件都已保存,然后在终端中运行flutter run来启动你的Flutter应用。你应该会看到一个简单的界面,显示了解析后的用户信息,并且有一个按钮可以将用户对象序列化为JSON字符串并打印到控制台。

这个示例展示了如何使用typed_json插件在Flutter中进行JSON解析和序列化。希望这对你有所帮助!

回到顶部