use*_*522 7 serialization json dart flutter
由于Flutter从它的SDK中取出了dart:mirror,因此不再可能像dartson这样的库使用JSON来对象序列化/反序列化.但是我读过build_value是达到类似目的的另一种方式.我找不到任何关于如何实施它的好例子,因为它包含大量的锅炉板代码.有人能举个例子吗?例如,这是我正在尝试序列化到对象的JSON:
{
"name":"John",
"age":30,
"cars": [
{ "name":"Ford", "models":[ "Fiesta", "Focus", "Mustang" ] },
{ "name":"BMW", "models":[ "320", "X3", "X5" ] },
{ "name":"Fiat", "models":[ "500", "Panda" ] }
]
}
Run Code Online (Sandbox Code Playgroud)
}
我希望从提供的答案中获得更多细节.尽管它们是很好的建议,但它们对我来说太过普遍了解.所以在做了我自己的研究之后,我将把我的实现分享给我提供的上述JSON示例,希望它可以节省别人的时间.以下是我遵循的步骤:
依赖关系:
built_value:^ 1.0.1
built_collection:^ 1.0.0dev_dependencies:
build_runner:^ 0.3.0
built_value_generator:^ 1.0.1
build.dart
// Copyright (c) 2015, Google Inc. Please see the AUTHORS file for details.
// All rights reserved. Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
import 'dart:async';
import 'package:build_runner/build_runner.dart';
import 'package:built_value_generator/built_value_generator.dart';
import 'package:source_gen/source_gen.dart';
/// Example of how to use source_gen with [BuiltValueGenerator].
///
/// Import the generators you want and pass them to [build] as shown,
/// specifying which files in which packages you want to run against.
Future main(List<String> args) async {
await build(
new PhaseGroup.singleAction(
new GeneratorBuilder([new BuiltValueGenerator()]),
new InputSet('built_value_example', const [
'lib/model/*.dart',
'lib/*.dart',
])),
deleteFilesByDefault: true);
}
Run Code Online (Sandbox Code Playgroud)
watch.dart
// Copyright (c) 2016, Google Inc. Please see the AUTHORS file for details.
// All rights reserved. Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
import 'dart:async';
import 'package:build_runner/build_runner.dart';
import 'package:built_value_generator/built_value_generator.dart';
import 'package:source_gen/source_gen.dart';
/// Example of how to use source_gen with [BuiltValueGenerator].
///
/// This script runs a watcher that continuously rebuilds generated source.
///
/// Import the generators you want and pass them to [watch] as shown,
/// specifying which files in which packages you want to run against.
Future main(List<String> args) async {
watch(
new PhaseGroup.singleAction(
new GeneratorBuilder([new BuiltValueGenerator()]),
new InputSet('built_value_example', const [
'lib/model/*.dart',
'lib/*.dart'])),
deleteFilesByDefault: true);
}
Run Code Online (Sandbox Code Playgroud)
serializers.dart
library serializers;
import 'package:built_collection/built_collection.dart';
import 'package:built_value/serializer.dart';
import 'package:built_value/standard_json_plugin.dart';
import 'model/person.dart';
part 'serializers.g.dart';
Serializers serializers = (
_$serializers.toBuilder()..addPlugin(new StandardJsonPlugin())
).build();
Run Code Online (Sandbox Code Playgroud)
person.dart
library person;
import 'package:built_collection/built_collection.dart';
import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';
part 'person.g.dart';
abstract class Person implements Built<Person, PersonBuilder> {
String get name;
int get age;
BuiltList<Car> get cars;
Person._();
factory Person([updates(PersonBuilder b)]) = _$Person;
static Serializer<Person> get serializer => _$personSerializer;
}
abstract class Car implements Built<Car, CarBuilder> {
String get name;
BuiltList<String> get models;
Car._();
factory Car([updates(CarBuilder b)]) = _$Car;
static Serializer<Car> get serializer => _$carSerializer;
}
Run Code Online (Sandbox Code Playgroud)
创建上面的4个文件后,它将显示一些编译器错误.不要介意他们.这是因为build.dart文件尚未运行.因此,在此步骤中,运行build.dart.如果您正在使用Webstorm,只需右键单击build.dart并点击"Run build.dart"即可.这将创建2个文件:"person.g.dart"和"serializers.g.dart".如果您仔细注意,在我们的build.dart文件中,我们将'lib/model/.dart'和'lib / .dart'放在一起.构建通过遍历指定的路径知道在哪里查找这些文件,并查找包含部分"内容"的文件.因此,在运行build.dart文件之前,将该行保留在这些文件中非常重要
最后,现在我可以在main.dart文件中使用序列化程序将json字符串序列化为我的自定义dart对象类Person.在我的main.dart中,我在initState()中添加了以下代码
main.dart
Person _person;
@override
void initState() {
super.initState();
String json = "{"
"\"name\":\"John\",\"age\":30,\"cars\": "
"["
"{ \"name\":\"Ford\", \"models\":[ \"Fiesta\", \"Focus\", \"Mustang\" ] },"
"{ \"name\":\"BMW\", \"models\":[ \"320\", \"X3\", \"X5\" ] },"
"{ \"name\":\"Fiat\", \"models\":[ \"500\", \"Panda\" ] }"
"]}";
setState(() {
_person = serializers.deserializeWith(
Person.serializer, JSON.decode(json));
});
}
Run Code Online (Sandbox Code Playgroud)
我的示例项目也可以在Github Built value示例项目中获得
Dart 团队的这个包在一个单独的文件中生成了fromJson
构造函数和toJson
方法所需的一切。
添加以下依赖项:
dependencies:
json_annotation: ^2.0.0
dev_dependencies:
build_runner: ^1.0.0
json_serializable: ^2.0.0
Run Code Online (Sandbox Code Playgroud)
调整您的模型类以具有以下部分:
import 'package:json_annotation/json_annotation.dart';
// will be generated later
part 'person.g.dart';
@JsonSerializable()
class Person {
Person(this.name, this.age);
final String name;
final int age;
factory Person.fromJson(Map<String, dynamic> json) =>
_$PersonFromJson(json);
Map<String, dynamic> toJson() => _$PersonToJson(this);
}
Run Code Online (Sandbox Code Playgroud)
从终端生成person.g.dart文件:
flutter packages pub run build_runner build
Run Code Online (Sandbox Code Playgroud)
然后像这样使用它:
JSON ? 目的
String rawJson = '{"name":"Mary","age":30}';
Map<String, dynamic> map = jsonDecode(rawJson);
Person person = Person.fromJson(map);
Run Code Online (Sandbox Code Playgroud)
目的 ?JSON
Person person = Person('Mary', 30);
Map<String, dynamic> map = person.toJson();
String rawJson = jsonEncode(map);
Run Code Online (Sandbox Code Playgroud)
pub run build_runner build
.您应该为Built_value准备一个配置文件,它将解析您的dart源并生成.g.dart。一旦准备好 json 序列化就会自动进行。您可以生成这些文件一次或使用 watch 命令。
这些文件将添加到与源和 dart 命令相同的级别
part of data;
Run Code Online (Sandbox Code Playgroud)
被视为同一类。
这是我在 Flutter 项目中使用的配置:
import 'dart:async';
import 'package:build_runner/build_runner.dart';
import 'package:built_value_generator/built_value_generator.dart';
import 'package:source_gen/source_gen.dart';
Future main(List<String> args) async {
await build(
new PhaseGroup.singleAction(
new GeneratorBuilder([
new BuiltValueGenerator(),
]),
new InputSet('flutter_project', const ['lib/data/*.dart'])),
deleteFilesByDefault: true);
}
Run Code Online (Sandbox Code Playgroud)
您可能会发现阅读 David Morgan 的所有帖子以了解其好处很有用。虽然需要一些时间来转变你的想法,但这是一个非常好的模式。
https://medium.com/dartlang/darts-built-value-for-immutable-object-models-83e2497922d4
https://medium.com/dartlang/darts-built-value-for-serialization-f5db9d0f4159
诀窍是了解 sourcegen 如何解析,然后通过添加许多行为(例如构建器和序列化器)来丰富您的类。
归档时间: |
|
查看次数: |
6283 次 |
最近记录: |