Flutter JSON模型转换插件convert_json_model的使用
Flutter JSON模型转换插件convert_json_model的使用
安装
在pubspec.yaml
文件中添加以下依赖:
dependencies:
convert_json_model: #最新版本
build_runner: ^2.0.1
json_annotation: ^4.0.1
json_serializable: ^4.1.1
安装这些依赖可以通过运行pub get
命令或者通过Dart VSCode/Android Studio的安装选项。
什么?为什么?怎么用?
什么
这是一个命令行工具,用于将.json
文件转换为.dart
模型文件,并最终生成.g.dart
文件(使用json_serializable
)。
为什么
问题
你可能有一个系统或后端REST应用程序,并且想要构建一个Dart应用。你可能开始创建数据模型。但是将Dart Map
转换为其他格式需要额外的工作,因此你可以使用json_serializable
,但仍然需要手动逐个输入模型。如果你有一个巨大的系统,需要大量的模型,那么编写所有的模型可能会让你感到压力。
解决方案
这个命令行工具可以让现有的.json
文件转换为Dart(json_serializable
)文件。
为什么不直接使用现有的命令行库json_model
?
json_model
非常棒,结构也很酷,但它不支持递归导入,这是我想要的功能。我还希望它能自动将变量名转换为驼峰命名法。我可以写一个issue并提交PR,但由于其代码结构不够清晰且可扩展性较差,而且我还看不懂它的注释,最后活跃在这个仓库的贡献者是在六月,我认为我不应该再等待了,所以我创建了一个新的工具。一些核心功能保持不变,但(也许)有更好的结构。
怎么做
它会遍历你的JSON文件,查找可能的类型、变量名、导入URI、装饰器和类名,并将其写入模板。
在项目根目录下创建/复制.json
文件到./jsons/
目录(默认),然后运行pub run convert_json_model
。
示例
{
"id": 2,
"title": "Hello Guys!",
"content": "$content",
"tags": "$[]tag",
"user_type": "[@enum](/user/enum):admin,app_user,normal",
"auth_state": "[@enum](/user/enum):verified(2),authenticated(1),guest(0)",
"user": "$../user/user",
"published": true
}
命令
pub run convert_json_model
或者
flutter pub run convert_json_model
输出
import 'package:json_annotation/json_annotation.dart';
import 'content.dart';
import 'tag.dart';
import '../user/user.dart';
part 'examples.g.dart';
[@JsonSerializable](/user/JsonSerializable)()
class Examples {
Examples();
int id;
String title;
Content content;
List<Tag> tags;
ExamplesUserTypeEnum
get examplesUserTypeEnum => _examplesUserTypeEnumValues.map[userType];
set examplesUserTypeEnum(ExamplesUserTypeEnum value) => userType = _examplesUserTypeEnumValues.reverse[value];
[@JsonKey](/user/JsonKey)(name: 'user_type') String userType;
ExamplesAuthStateEnum
get examplesAuthStateEnum => _examplesAuthStateEnumValues.map[authState]!;
set examplesAuthStateEnum(ExamplesAuthStateEnum value) => authState = _examplesAuthStateEnumValues.reverse[value];
[@JsonKey](/user/JsonKey)(name: 'auth_state') int authState;
User user;
bool published;
factory Examples.fromJson(Map<String,dynamic> json) => _$ExamplesFromJson(json);
Map<String, dynamic> toJson() => _$ExamplesToJson(this);
}
enum ExamplesUserTypeEnum { Admin, AppUser, Normal }
enum ExamplesAuthStateEnum { Verified, Authenticated, Guest }
final _examplesUserTypeEnumValues = _ExamplesUserTypeEnumConverter({
'admin': ExamplesUserTypeEnum.Admin,
'app_user': ExamplesUserTypeEnum.AppUser,
'normal': ExamplesUserTypeEnum.Normal,
});
final _examplesAuthStateEnumValues = _ExamplesAuthStateEnumConverter({
2: ExamplesAuthStateEnum.Verified,
1: ExamplesAuthStateEnum.Authenticated,
0: ExamplesAuthStateEnum.Guest,
});
class _ExamplesUserTypeEnumConverter<String, O> {
Map<String, O> map;
Map<O, String>? reverseMap;
_ExamplesUserTypeEnumConverter(this.map);
Map<O, String> get reverse => reverseMap ??= map.map((k, v) => MapEntry(v, k));
}
class _ExamplesAuthStateEnumConverter<int, O> {
Map<int, O> map;
Map<O, int>? reverseMap;
_ExamplesAuthStateEnumConverter(this.map);
Map<O, int> get reverse => reverseMap ??= map.map((k, v) => MapEntry(v, k));
}
开始使用
- 在项目的根目录下创建一个名为
jsons
的目录(默认)。 - 将所有或创建的json文件放入
jsons
目录。 - 运行
pub run convert_json_model
。如果是Flutter项目,可以使用flutter packages pub run convert_json_model
。
使用方法
该包将读取.json
文件,并生成.dart
文件,将值的类型
作为变量类型
,并将键
作为变量名
。
描述 | 表达式 | 输入(示例) | 输出(声明) | 输出(导入) |
---|---|---|---|---|
声明类型取决于JSON值 | {…: any type} | {“id”: 1, “message”:“hello world”} | int id; String message; |
- |
导入模型并指定类型 | {…: “$value”} | {“auth”:"$user"} | User auth; | import ‘user.dart’ |
递归导入 | {…: “$…/pathto/value”} | {“price”:"$…/product/price"} | Price price; | import ‘…/product/price.dart’ |
指定类型列表并导入(也可以递归) | {…: “$[]value”} | {“addreses”:"$[]address"} | List addreses; | import ‘address.dart’ |
使用json_annotation [@JsonKey](/user/JsonKey) |
{…: “@JsonKey(…)”} | {"@JsonKey(ignore: true) dynamic": “val”} | @JsonKey(ignore: true) dynamic val; | - |
导入其他库(输入值可以是数组) | {…: “@import”} | {"@import":“package:otherlibrary/otherlibrary.dart”} | - | import ‘package:otherlibrary/otherlibrary.dart’ |
日期时间类型 | {…: “@datetime”} | {“createdAt”: “@datetime:2020-02-15T15:47:51.742Z”} | DateTime createdAt; | - |
枚举类型 | {…: “@enum:(folowed by enum separated by ‘,’)”} | {"@import":"@enum:admin,app_user,normal"} | enum UserTypeEnum { Admin, AppUser, Normal }(包含变量声明) | - |
枚举类型带值 | {…: “@enum:(folowed by enum separated by ‘,’)”} | {"@import":"@enum:admin(0),app_user(1),normal(2)"} | enum UserTypeEnum { Admin, AppUser, Normal }(包含变量声明) | - |
独立编写代码(实验性) | {…: “@_…”} | {"@_ // any code here":",its like an escape to write your own code"} | // any code here,its like an escape to write your own code | - |
示例
你可以复制以下JSON,并使用pub run convert_json_model
命令生成。
基本示例
源文件
./jsons/user.json
{
"id": 2,
"username": "John Doe",
"blocked": false
}
生成的文件
./lib/models/user.dart
import 'package:json_annotation/json_annotation.dart';
part 'user.g.dart';
[@JsonSerializable](/user/JsonSerializable)()
class User {
User();
int id;
String username;
bool blocked;
factory User.fromJson(Map<String,dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}
之后,json_serializable
会自动生成.g.dart
文件。
./lib/models/user.g.dart
part of 'user.dart';
User _$UserFromJson(Map<String, dynamic> json) {
return User()
..id = json['id'] as int
..username = json['username'] as String
..blocked = json['blocked'] as bool;
}
Map<String, dynamic> _$UserToJson(User instance) => <String, dynamic>{
'id': instance.id,
'username': instance.username,
'blocked': instance.blocked,
};
指定类型变量
你可以使用$
来指定变量的类型。
源文件
./jsons/user.json
{
"id": 2,
"username": "John Doe",
"blocked": false,
"addresses": "$address" // 前缀 $
}
在这种情况下,$address
类似于告诉生成器导入address.dart
并将标题大小写的Address
作为变量addresses
的类型。
生成的文件
./lib/models/user.dart
import 'package:json_annotation/json_annotation.dart';
import 'address.dart'; // 自动导入
part 'user.g.dart';
[@JsonSerializable](/user/JsonSerializable)()
class User {
User();
int id;
String username;
bool blocked;
Address addresses; // $address 转换为 Address 类型
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}
指定列表类型变量
你可以使用$[]
来指定变量的列表类型。
源文件
./jsons/user.json
{
"id": 2,
"username": "John Doe",
"blocked": false,
"addresses": "$[]address" // 前缀 $[]
}
生成的文件
./lib/models/user.dart
import 'package:json_annotation/json_annotation.dart';
import 'address.dart'; // 编写地址作为导入
part 'user.g.dart';
[@JsonSerializable](/user/JsonSerializable)()
class User {
User();
int id;
String username;
bool blocked;
List<Address> addresses; // 列表类型
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}
使用json_serializable
[@JsonKey](/user/JsonKey)
你可以在key
中使用[@JsonKey](/user/JsonKey)
来指定[@JsonKey](/user/JsonKey)
。
源文件
./jsons/cart.json
{
"[@JsonKey](/user/JsonKey)(ignore: true) dynamic": "md", // jsonKey别名
"[@JsonKey](/user/JsonKey)(name: '+1') int": "loved", // jsonKey别名
"name": "wendux",
"age": 20
}
生成的文件
./lib/models/cart.dart
import 'package:json_annotation/json_annotation.dart';
part 'cart.g.dart';
[@JsonSerializable](/user/JsonSerializable)()
class Cart {
Cart();
[@JsonKey](/user/JsonKey)(ignore: true) dynamic md; // 生成jsonKey
[@JsonKey](/user/JsonKey)(name: '+1') int loved; // 生成jsonKey
String name;
int age;
factory Cart.fromJson(Map<String,dynamic> json) => _$CartFromJson(json);
Map<String, dynamic> toJson() => _$CartToJson(this);
}
词汇表
实体
imports
: 导入语句字符串。从.json
文件中获取前缀为$
的值,后缀为.dart
并插入import '$import';\n
。fileName
: 文件名。从.json
文件中获取前缀为$
的值,但非单词字符(\W
)被移除,并转换为驼峰命名法。className
: 类名。基本上是fileName
,但转换为标题大小写。declarations
: 声明语句字符串。基本上是<a href="https://github.com/linlak/convert_json_model/blob/master/lib/core/dart_declaration.dart" rel="ugc">DartDeclaration</a>
对象的列表,并转换为toString()
。enums
: 任何标记为[@enum](/user/enum)
的语句将被解析并添加到生成的dart语句中。enumConverters
: 为了自动绑定枚举字符串值到实际枚举使用转换器。
模板
String defaultTemplate({
imports,
fileName,
className,
declarations,
enums,
}) => """
import 'package:json_annotation/json_annotation.dart';
$imports
part '$fileName.g.dart';
[@JsonSerializable](/user/JsonSerializable)()
class $className {
$className();
$declarations
factory $className.fromJson(Map<String,dynamic> json) => _\$${className}FromJson(json);
Map<String, dynamic> toJson() => _\$${className}ToJson(this);
}
$enums
""";
更多关于Flutter JSON模型转换插件convert_json_model的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter JSON模型转换插件convert_json_model的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
convert_json_model
是一个用于 Flutter 的代码生成插件,它可以根据 JSON 数据自动生成 Dart 数据模型类。这可以帮助开发者快速生成与 JSON 数据对应的 Dart 类,从而简化 JSON 数据的解析和序列化过程。
安装 convert_json_model
首先,你需要在 pubspec.yaml
文件中添加 convert_json_model
依赖项:
dependencies:
flutter:
sdk: flutter
dev_dependencies:
convert_json_model: ^0.0.1
然后运行 flutter pub get
来安装依赖。
使用 convert_json_model
-
创建 JSON 文件
首先,你需要创建一个包含 JSON 数据的文件。例如,在
lib/models
目录下创建一个user.json
文件:{ "name": "John Doe", "age": 30, "email": "john.doe@example.com", "address": { "street": "123 Main St", "city": "Anytown" } }
-
运行代码生成器
运行以下命令来生成 Dart 数据模型类:
flutter pub run convert_json_model
这将会根据
user.json
文件生成一个user.dart
文件,内容如下:class User { final String name; final int age; final String email; final Address address; User({ required this.name, required this.age, required this.email, required this.address, }); factory User.fromJson(Map<String, dynamic> json) { return User( name: json['name'], age: json['age'], email: json['email'], address: Address.fromJson(json['address']), ); } Map<String, dynamic> toJson() { return { 'name': name, 'age': age, 'email': email, '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, }; } }
-
使用生成的模型类
现在你可以使用生成的
User
和Address
类来解析和序列化 JSON 数据。例如:import 'models/user.dart'; void main() { final jsonString = ''' { "name": "John Doe", "age": 30, "email": "john.doe@example.com", "address": { "street": "123 Main St", "city": "Anytown" } } '''; final Map<String, dynamic> userMap = jsonDecode(jsonString); final User user = User.fromJson(userMap); print('User Name: ${user.name}'); print('User Address: ${user.address.street}, ${user.address.city}'); final Map<String, dynamic> userJson = user.toJson(); print('User JSON: $userJson'); }
配置 convert_json_model
你可以在 build.yaml
文件中配置 convert_json_model
的行为。例如,指定输入目录和输出目录:
targets:
$default:
builders:
convert_json_model|json_model:
options:
input_folder: "lib/models/json"
output_folder: "lib/models"