Flutter JSON字符串处理插件json_string的使用

发布于 1周前 作者 yuanlaile 来自 Flutter

Flutter JSON字符串处理插件json_string的使用

简介

json_string 是一个简单且轻量级的 JSON 数据容器,适用于 Dart 和 Flutter。它不仅保持了 JSON 数据的简洁性,还直接封装了 dart:convert 库,提供了更好的类型安全性和更清晰的语法。

为什么使用 json_string

  1. 类型安全性json_string 提供了类型安全的编码和解码方法,避免了使用 dart:convert 时可能出现的类型不安全问题。
  2. 简洁性json_string 保持了 JSON 数据的简洁性,同时提供了丰富的操作方法。
  3. 封装性:直接封装了 dart:convert 库,使得 JSON 处理更加方便。

配置

pubspec.yaml 文件中添加 json_string 依赖:

dependencies:
  json_string: ^3.0.1

安装

使用 pubflutter 命令安装依赖包:

$ pub get

$ flutter pub get

导入

在你的库文件中导入 json_string 包:

import 'package:json_string/json_string.dart';

使用方法

概览

检查 JSON 字符串的有效性

使用默认构造函数检查字符串是否为有效的 JSON:

try {
  final jsonString = JsonString('{"username":"john_doe","password":"querty"}');
  // ...
} on JsonFormatException catch (e) {
  print('Invalid JSON format: $e');
}

或者处理空值:

final jsonString = JsonString.orNull('{"username":"john_doe","password":"querty"}');

if (jsonString == null) {
  print('Invalid JSON format');
}
// ...

访问数据

通过 source 属性访问原始 JSON 字符串:

final source = jsonString.source;

print(source); // {"username":"john_doe","password":"querty"}

或者读取解码后的对象:

final credentials = jsonString.decodedValue;

print(credentials['username']); // john_doe
print(credentials['password']); // querty

编码

JsonString 提供了多种方法来编码 Dart 类型,所有方法都是类型安全的。

平面对象

标记为 Jsonable 的类需要实现 toJson() 方法:

class User with Jsonable {
  String username;
  String password;

  User({
    required this.username,
    required this.password,
  });

  @override
  Map<String, dynamic> toJson() => <String, dynamic>{
        'username': username,
        'password': password,
      };
}

final user = User(username: 'john_doe', password: 'qwerty');
final jsonString = JsonString.encodeObject(user);

或者提供一个自定义的编码器:

final jsonString = JsonString.encodeObject(user, encoder: (u) => {
  'ba': btoa("${u.username}:${u.password}"),
});

对象列表

编码对象列表:

final userList = [
  User(username: 'john_doe', password: 'qwerty'),
  User(username: 'clara_brothers', password: 'asdfgh')
];

// 默认编码
final jsonString1 = JsonString.encodeObjectList(userList);

// 自定义编码
final jsonString2 = JsonString.encodeObjectList(userList, encoder: (u) => {
  'ba': btoa("${u.username}:${u.password}"),
});

原始值列表

编码原始值列表(整数、双精度浮点数、字符串、布尔值或空值):

// 整数
final fibonacci = [1, 1, 2, 3, 5, 8, 13];
final jsonString = JsonString.encodePrimitiveList(fibonacci);

// 字符串
final message = ["h", "e", "l", "l", "o", "!"];
final jsonString = JsonString.encodePrimitiveList(message);

// 双精度浮点数
final temperatures = [16.0, 18.0, 21.0, 19.0];
final jsonString = JsonString.encodePrimitiveList(temperatures);

// 布尔值
final flags = [false, false, true, false];
final jsonString = JsonString.encodePrimitiveList(flags);

// 空值
final usefulList = [null, null, null, null];
final jsonString = JsonString.encodePrimitiveList(usefulList);

单个原始值

编码单个原始值:

// 整数
final answer = 42;
final jsonString = JsonString.encodePrimitiveValue(answer);

// 字符串
final message = "hello!";
final jsonString = JsonString.encodePrimitiveValue(message);

// 双精度浮点数
final pi = 3.14159;
final jsonString = JsonString.encodePrimitiveValue(pi);

// 布尔值
final amIaGenius = false;
final jsonString = JsonString.encodePrimitiveValue(amIaGenius);

// 空值
final usefulValue = null;
final jsonString = JsonString.encodePrimitiveValue(usefulValue);

解码

json_string 提供了多种方法来解码 JSON 数据。

属性

访问解码后的值:

// 任何类型
final decodedValue = jsonString.decodedValue;

如果已知数据类型,可以使用 decodedValueAsMapdecodedValueAsList

// 对象预期
try {
  final decodedObject = jsonString.decodedValueAsMap;
  print(decodedObject.runtimeType); // Map<String, dynamic>
} on JsonDecodingError catch (e) {
  throw "This is not an object.";
}

// 列表预期
try {
  final decodedList = jsonString.decodedValueAsList;
  print(decodedList.runtimeType); // List<dynamic>
} on JsonDecodingError catch (e) {
  throw "This is not a list.";
}

方法

解码方法与编码方法类似,只是方向相反。

平面对象和对象列表(非空)
class User {
  String username;
  String password;

  User({
    required this.username,
    required this.password,
  });

  static User fromJson(Map<String, dynamic> json) => User(
        username: json['username'] as String,
        password: json['password'] as String,
      );
}

// 对象解码
final jsonString = JsonString('{"username":"john_doe","password":"querty"}');

final user = jsonString.decodeAsObject(User.fromJson);

// 对象列表解码
final jsonString = JsonString('''[
  {"username":"john_doe","password":"querty"},
  {"username":"clara_brothers","password":"asdfgh"}
]''');

final userList = jsonString.decodeAsObjectList(User.fromJson);
平面对象和对象列表(可空)
class User {
  String? username;
  String? password;

  User({
    this.username,
    this.password,
  });

  static User fromJson(Map<String, dynamic>? json) => User(
        username: json?['username'] as String?,
        password: json?['password'] as String?,
      );
}

// 对象解码
final jsonString = JsonString('null');

final user = jsonString.decodeAsNullableObject(User.fromJson);

// 对象列表解码
final jsonString = JsonString('''[
  {"username":"john_doe","password":"querty"},
  null
]''');

final userList = jsonString.decodeAsNullableObjectList(User.fromJson);
原始值列表
// 整数列表解码
final jsonString = JsonString('[1, 1, 2, 3, 5, 8, 13]');
final fibonacci = jsonString.decodeAsPrimitiveList<int>();

// 字符串列表解码
final jsonString = JsonString('["h", "e", "l", "l", "o", "!"]');
final message = jsonString.decodeAsPrimitiveList<String>();

// 双精度浮点数列表解码
final jsonString = JsonString('[16.0, 18.0, 21.0, 19.0]');
final temperatures = jsonString.decodeAsPrimitiveList<double>();

// 布尔值列表解码
final jsonString = JsonString('[false, false, true, false]');
final flags = jsonString.decodeAsPrimitiveList<bool>();
单个原始值
// 整数值解码
final jsonString = JsonString('42');
final answer = jsonString.decodeAsPrimitiveValue<int>();

// 字符串值解码
final jsonString = JsonString('hello!');
final message = jsonString.decodeAsPrimitiveValue<String>();

// 双精度浮点数值解码
final jsonString = JsonString('3.14159');
final pi = jsonString.decodeAsPrimitiveValue<double>();

// 布尔值解码
final jsonString = JsonString('false');
final amIaGenius = jsonString.decodeAsPrimitiveValue<bool>();
可空的原始值列表和值
// 可空的整数列表解码
final jsonString = JsonString('[42, null, 25, 74, null]');
final availableAges = jsonString.decodeAsPrimitiveList<int?>();

// 可空的整数值解码
final jsonString = JsonString('null');
final maybeAnswer = jsonString.decodeAsPrimitiveValue<int?>();

高级用法

复杂编码

编码复杂结构:

const data = [{
  "key0": [1, 2, 3],
  "key1": 123,
  "key2": "123",
}, "value1", false];
try {
  final jsonString = JsonString.encode(data);
  // ...
} on JsonEncodingError catch (e) {
  print('${data.toString()} is impossible to encode : $e');
}

缓存

解码操作可能耗时且占用计算资源。可以通过设置 enableCache 标志来缓存解码后的值,从而提高性能:

final jsonString = JsonString(source, enableCache: true);
final decodedMap = jsonString.decodedValueAsMap; // 立即访问

关闭 Jsonable 检查

如果不希望使用 Jsonable,可以在编码对象时将 checkIfJsonable 设置为 false

// singleObject 不是 Jsonable 对象
final jsonString = JsonString.encodeObject(singleObject, checkIfJsonable: false);
// objectList 不是 Jsonable 对象列表
final jsonString = JsonString.encodeObjectList(objectList, checkIfJsonable: false);

示例代码

以下是一个完整的示例代码,展示了如何使用 json_string 进行 JSON 编码和解码:

import 'package:collection/collection.dart';
import 'package:json_string/json_string.dart';

void main() {
  const externalSource = '{"username":"john_doe","password":"querty"}';
  var jsonString = JsonString.orNull(externalSource);
  if (jsonString == null) {
    print('Bad source!');
    return;
  }
  final user1 = jsonString.decodeAsObject(User.fromJson);
  final user2 = User(username: 'clara_brothers', password: 'asdfgh');
  final userList = [user1, user2];

  jsonString = JsonString.encodeObjectList(userList);
  final internalSource = jsonString.source;
  print(internalSource);

  final decodedList = jsonString.decodeAsObjectList(User.fromJson);
  print(ListEquality<User>().equals(decodedList, userList)); // true
}

class User with Jsonable {
  String username;
  String password;

  User({
    required this.username,
    required this.password,
  });

  static User fromJson(Map<String, dynamic> json) => User(
        username: json['username'] as String,
        password: json['password'] as String,
      );

  @override
  Map<String, dynamic> toJson() => <String, dynamic>{
        'username': username,
        'password': password,
      };

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is User &&
          runtimeType == other.runtimeType &&
          username == other.username &&
          password == other.password;
}

通过以上内容,你可以轻松地在 Flutter 项目中使用 json_string 插件进行 JSON 字符串的处理。


更多关于Flutter JSON字符串处理插件json_string的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter JSON字符串处理插件json_string的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在处理Flutter中的JSON字符串时,json_string 并不是一个广泛认知的标准插件。通常,Flutter 开发者使用 Dart 内置的 dart:convert 库来处理 JSON 数据。不过,如果你提到的 json_string 是一个自定义的或者第三方插件,并且它的功能类似于 dart:convert,那么处理 JSON 字符串的基本思路是相似的。

下面,我将展示如何使用 Dart 内置的 dart:convert 库来处理 JSON 字符串,因为这是一个标准且广泛使用的方法。如果你确实在使用一个名为 json_string 的插件,并且其功能与 dart:convert 类似,你可以相应地调整代码。

使用 dart:convert 处理 JSON 字符串

1. 解析 JSON 字符串到 Dart 对象

假设你有一个 JSON 字符串,如下所示:

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

首先,定义一个 Dart 类来匹配这个 JSON 结构:

class User {
  String name;
  int age;
  String email;

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

  // 从 JSON 映射构造 User 对象
  factory User.fromJson(Map<String, dynamic> json) {
    return User(
      name: json['name'] as String,
      age: json['age'] as int,
      email: json['email'] as String,
    );
  }

  // 将 User 对象转换为 JSON 映射
  Map<String, dynamic> toJson() {
    return {
      'name': name,
      'age': age,
      'email': email,
    };
  }
}

然后,使用 jsonDecode 函数解析 JSON 字符串:

import 'dart:convert';

void main() {
  String jsonString = '''
  {
    "name": "John Doe",
    "age": 30,
    "email": "johndoe@example.com"
  }
  ''';

  // 解析 JSON 字符串到 Map
  Map<String, dynamic> userMap = jsonDecode(jsonString);

  // 使用工厂构造函数从 Map 创建 User 对象
  User user = User.fromJson(userMap);

  print('Name: ${user.name}');
  print('Age: ${user.age}');
  print('Email: ${user.email}');
}

2. 将 Dart 对象转换为 JSON 字符串

使用 jsonEncode 函数将 Dart 对象转换为 JSON 字符串:

import 'dart:convert';

void main() {
  User user = User(name: 'Jane Doe', age: 25, email: 'janedoe@example.com');

  // 将 User 对象转换为 JSON 字符串
  String jsonString = jsonEncode(user.toJson());

  print(jsonString);
}

在这个例子中,user.toJson() 方法被用来将 User 对象转换为一个 Map<String, dynamic>,然后 jsonEncode 函数将这个 Map 转换为一个 JSON 字符串。

如果使用 json_string 插件(假设存在)

如果你确实在使用一个名为 json_string 的插件,并且它的 API 类似于 dart:convert,那么你可以这样使用它(假设它有相应的 decodeencode 方法):

import 'package:json_string/json_string.dart'; // 假设这是插件的导入路径

void main() {
  // 解析 JSON 字符串(假设 json_string 插件有 decode 方法)
  String jsonString = '{"name": "John Doe", "age": 30, "email": "johndoe@example.com"}';
  Map<String, dynamic> userMap = JsonString.decode(jsonString);

  // ... 这里可以使用 userMap 构造你的 User 对象,类似于上面的例子 ...

  // 将 Dart 对象转换为 JSON 字符串(假设 json_string 插件有 encode 方法)
  User user = User(name: 'Jane Doe', age: 25, email: 'janedoe@example.com');
  String encodedJsonString = JsonString.encode(user.toJson());

  print(encodedJsonString);
}

请注意,上述 JsonString.decodeJsonString.encode 方法是假设的,你需要根据你实际使用的 json_string 插件的文档来调整代码。如果 json_string 插件的 API 与 dart:convert 不同,请参考该插件的官方文档以获取正确的使用方法。

回到顶部