联合上一篇介绍[Flutter]Json和序列化数据,看欣赏关注的人还是许多。这里出一篇详细介绍json_serializable的属性参数的分析阐明。此文章根据现在最新版本json_serializable: ^6.9.0介绍 ,下面开始:
一、一般利用介绍
- // json_serializable模型写法示意
- import 'package:json_annotation/json_annotation.dart';
- //当前文件名+.g.dart
- part 'device_model.g.dart';
- //添加注解
- @JsonSerializable()
- class DeviceTypeNetModel {
- final num? deviceType;
- final String? deviceTypeName;
- //自定义一些属性的某些设置
- @JsonKey(name: 'num')
- final int? count;
- //构造函数
- DeviceTypeNetModel(this.deviceType, this.deviceTypeName, this.count);
- //工厂构造函数fromJson(也可以不写,需要配置对应的设置)
- factory DeviceTypeNetModel.fromJson(Map<String, dynamic> json) =>
- _$DeviceTypeNetModelFromJson(json);
- //转json (也可以不写,需要配置对应的设置)
- Map<String, dynamic> toJson() => _$DeviceTypeNetModelToJson(this);
- }
复制代码 二、JsonKey参数分析
defaultValue:Object?
- 功能:指定字段的默认值。当 JSON 中没有该字段时,将利用 defaultValue 提供的值。
- 用法:如果 JSON 数据中某个字段缺失,defaultValue 可以为其提供默认值,避免字段变为 null 或触发错误。
- @JsonKey(defaultValue: 'Unknown')
- final String name;
复制代码 如果 JSON 数据中没有 name 字段,默认值 Unknown 会被利用。
disallowNullValue:bool?
- 功能:用于toJson的时间防止字段值为 null,如果字段的值为 null,会抛出 ArgumentError。
- 用法:用于要求某个字段永远不能为 null,如果传入 null,则会抛出非常。
- @JsonKey(disallowNullValue: true)
- final String name;
复制代码 如果 name 字段为 null,在序列化时将抛堕落误。
fromJson 和 toJson : Function?
- 功能:用于指定自定义的序列化和反序列化函数。这对于复杂的数据类型或者必要特别处置惩罚的字段特别有用。
- 用法:可以通过 fromJson 来指定如何将 JSON 数据转换为 Dart 对象,toJson 用于指定如何将 Dart 对象转换为 JSON。
- @JsonKey(fromJson: _fromJson, toJson: _toJson)
- final DateTime timestamp;
- static DateTime _fromJson(String timestamp) {
- return DateTime.parse(timestamp);
- }
- static String _toJson(DateTime timestamp) {
- return timestamp.toIso8601String();
- }
复制代码 这里,timestamp 字段会利用自定义的 fromJson 和 toJson 方法举行分析和序列化。
name: String?
- 功能:用于指定字段在 JSON 中的键名。通常在 Dart 类字段名与 JSON 中的键名不匹配时利用。
- 用法:如果 Dart 类中的字段名与 JSON 中的字段名不一致,可以利用 name 指定要利用的 JSON 键。
- @JsonKey(name: 'full_name')
- final String name;
复制代码 在上面的示例中,name 字段会被序列化为 full_name,而不是默认的 name。
includeFromJson 和 includeToJson : bool?
- 功能:如果设置为 true,该字段将被忽略,在 toJson 和 fromJson 中都不会到场序列化和反序列化。不会影响模子基准构造函数的赋值利用。
- 用法:用于那些不希望在 JSON 中举行序列化和反序列化的字段。
- @JsonKey(includeFromJson: true,includeToJson: true)
- final String temporaryData;
复制代码 这里,temporaryData 字段将不会出现在天生的 JSON 中,而且也不会到场 fromJson 过程。
includeIfNull:bool?
- 功能:用于控制字段是否在 toJson 时包罗 null 值。如果设置为 false,该字段纵然为 null 也会被忽略。(默认从默认配置中获取即为true)
- 用法:常用于希望在序列化时避免天生冗余的 null 字段。
- @JsonKey(includeIfNull: false)
- final String? email;
复制代码 如果 email 字段为 null,它将不会出现在天生的 JSON 中。
readValue: Object? Function(Map,Srting)?
- 功能:用于转化接口返回的类型。(有范围性,建议利用fromJson和toJson替换)
- 用法:常用于希望在吸收利用的数据类型和接口返回的json中字段类型不一致的情况。
- @JsonKey(readValue: NormalTool.transFromMill)
- final String timeMill;
- class NormalTool {
- static String transFromMill(Map p0, String p1) {
- return p0[p1].toString();
- }
- }
复制代码 //留意这里转化基本类型可以,但是如果是DateTime类型会出现不属于基本类型的转化toJson会被定义为String,进而影响fromJson的转化。
比方上述的如果转化为DateTime,得到的.g.dart的转化内容如下:
- DeviceTypeNetModel _$DeviceTypeNetModelFromJson(Map<String, dynamic> json) =>
- DeviceTypeNetModel(
- DateTime.parse(NormalTool.transFromMill(json, 'timeMill') as String),
- );
- Map<String, dynamic> _$DeviceTypeNetModelToJson(DeviceTypeNetModel instance) =>
- <String, dynamic>{
- 'timeMill': instance.timeMill.toIso8601String(),
- };
复制代码
required:bool?
- 功能:表示该字段在 JSON 中是必须的,必须提供该字段的值。和构造函数标注属性必须有内容雷同。
- 用法:当你必要确保某个字段在序列化时不为 null 而且 JSON 中必须包罗该字段时,可以利用此属性。
- @JsonKey(required: true)
- final String name;
复制代码 这意味着,name 字段在 JSON 中是必须存在的,否则分析时会抛出非常。
unknownEnumValue : Enum?
- 功能:用于处置惩罚摆列类型的字段。当 JSON 数据包罗一个未在 Dart 摆列中定义的值时,利用 unknownEnumValue 来指定默认值。
- 用法:非常有用,尤其是在处置惩罚与外部 API 交互时,API 大概会传回新的、未在摆列中定义的值。
- @JsonKey(unknownEnumValue: Gender.other)
- final Gender gender;
复制代码 如果 JSON 中的 gender 字段值不是摆列中定义的 male、female,则默认利用 Gender.other。
三、JsonSerializable参数分析
anyMap:bool?
- 类型:bool,默认值是 false。
- 描述:如果为 true,则会将 Map 的 fromJson 方法天生的参数类型从 Map 改为 Map。这可以用于处置惩罚一些动态类型的数据。
- @JsonSerializable(anyMap: true)
- class User {
- final String name;
- User({required this.name});
- }
复制代码
checked: bool?
- 类型:bool,默认值是 false。
- 描述:如果为 true,则会将fromJson按照类型校验类型正确的反序列化,如果类型校验不通过则会抛出非常CheckedFromJsonException
- @JsonSerializable(checked: true)
- class User {
- final String name;
- User({required this.name});
- }
复制代码
constructor: String?
- 类型:String?,默认值是 null。
- 描述:指定一个构造函数的名称。如果你的类有多个构造函数,或者必要通过特定的构造函数来创建对象,可以利用此参数。
- @JsonSerializable(constructor: 'customConstructor')
- class User {
- final String name;
- User.customConstructor({required this.name});
- }
复制代码 在这个例子中,User 类会利用 customConstructor 来天生实例。
createFieldMap: bool?
- 类型:bool,默认值是 false。
- 描述:如果为 true,则会创建一个私有的方法_$ExampleJsonMeta 返回模子名称对应Json的key
- @JsonSerializable(createFieldMap: true)
- class DeviceTypeNetModel {
- final num? deviceType;
- final String? deviceTypeName;
- @JsonKey(name: 'num')
- final int? count;
- final DeviceListCountNetModel model;
-
- DeviceTypeNetModel(this.deviceType, this.deviceTypeName, this.count, this.model);
-
- Map<String, String> fieldMap() => _$DeviceTypeNetModelFieldMap;
- }
- .g.dart 会多一个内部私有方法
- const _$DeviceTypeNetModelFieldMap = <String, String>{
- 'deviceType': 'deviceType',
- 'deviceTypeName': 'deviceTypeName',
- 'count': 'num',
- 'model': 'model',
- };
复制代码
createJsonKeys: bool?
- 类型:bool,默认值是 false。
- 描述:同上createFieldMap,内部创建一个私有的_$ExampleJsonKeys,创建一个静态的字符常量定义,变量名为项目属性名,指向内容是Json的key。
- @JsonSerializable(createJsonKeys: true)
- class DeviceTypeNetModel {
- final num? deviceType;
- final String? deviceTypeName;
- @JsonKey(name: 'num')
- final int? count;
- final DeviceListCountNetModel model;
-
- DeviceTypeNetModel(this.deviceType, this.deviceTypeName, this.count, this.model);
- }
- .g.dart 会多一个内部私有方法
- abstract final class _$DeviceTypeNetModelJsonKeys {
- static const String deviceType = 'deviceType';
- static const String deviceTypeName = 'deviceTypeName';
- static const String count = 'num';
- static const String model = 'model';
- }
复制代码
createFactory: bool?
- 描述:如果为 false,不会为该类天生 fromJson 工厂方法。可以通过手动定义 fromJson 工厂方法来控制反序列化过程。
- @JsonSerializable(createFactory: false)
- class User {
- final String name;
- User({required this.name});
- // 手动定义 fromJson 方法
- static User fromJson(Map<String, dynamic> json) {
- return User(name: json['name']);
- }
- }
复制代码
createToJson: bool?
- 类型:bool,默认值是 true。
- 描述:如果为 false,则不天生 toJson 方法。你可以手动定义自己的 toJson 方法,或者完全不必要序列化成 JSON。
- @JsonSerializable(createToJson: false)
- class User {
- final String name;
- User({required this.name});
- // 手动定义 toJson 方法
- Map<String, dynamic> toJson() {
- return {'name': name};
- }
复制代码
disallowUnrecognizedKeys: bool?
- 类型:bool,默认值是 false。
- 描述:默认false,表示fromJson中的JSON有多余的字段忽略,如果设置为true,则JSON存在多余的key会抛出非常}UnrecognizedKeysException
explicitToJson: bool?
- 描述:如果为 true,则嵌套对象的 toJson 方法会被显式调用。默认情况下,json_serializable 会递归地将对象转化为 JSON,而不必要显式调用嵌套类的 toJson 方法。如果你希望强制嵌套对象也利用自己的 toJson,可以设置为 true。
- @JsonSerializable(explicitToJson: true)
- class User {
- final String name;
- final Address address;
- User({required this.name, required this.address});
- factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
- Map<String, dynamic> toJson() => _$UserToJson(this);
- }
- @JsonSerializable()
- class Address {
- final String city;
- final String street;
- Address({required this.city, required this.street});
- factory Address.fromJson(Map<String, dynamic> json) => _$AddressFromJson(json);
- Map<String, dynamic> toJson() => _$AddressToJson(this);
- }
复制代码 在这个例子中,User 类会显式调用 Address 类的 toJson,而不依赖于 json_serializable 的递归主动处置惩罚。
fieldRename: FieldRename?
- 类型:FieldRename,可以设置为 none(默认值),snake , kebab,pascal,screamingSnake。
- 描述:指定字段名的转换规则,通常用于处置惩罚 Dart 中的驼峰定名和 JSON 中的下划线定名。
- none:保留原字段名(默认值)。
- snake:将字段名转换为蛇形定名(camelCase -> snake_case)。
- kebab:将字段名转换为短横线定名(camelCase -> kebab-case)。
- pascal: 将字段名转换为大驼峰定名(pascalCase -> PascalCase)。
- screamingSnake: 将字段名转换为单词大写下划线连接 (screamingSnakeCase -> SCREAMING_SNAKE_CASE)。
- @JsonSerializable(fieldRename: FieldRename.snake)
- class User {
- final String firstName;
- final String lastName;
- User({required this.firstName, required this.lastName});
- }
复制代码 在这个例子中,firstName 会被转换为 first_name,lastName 会被转换为 last_name。
ignoreUnannotated: bool?
- 类型:bool,默认值是 false。
- 描述:如果为 true,则 json_serializable 会忽略没有被 @JsonKey 标注的字段。这对于类中有许多字段,但只希望某些字段举行序列化时非常有用。
- @JsonSerializable(ignoreUnannotated: true)
- class User {
- final String name;
- @JsonKey(name: 'age_in_years')
- final int age;
- User({required this.name, required this.age});
- }
复制代码 如果你设置了 ignoreUnannotated: true,name 字段不会被包罗在天生的 toJson 和 fromJson 方法中,只有 age 字段会被序列化。
includeIfNull: bool?
- 类型:bool,默认值是 true。
- 描述:针对toJson,如果值是null的时间是否写入导出的JSON中。
converters: List?
- 类型:List
- 描述:自定义表明器,内部的fromJson和toJson都将自定义实现,取消主动天生的转化。
- @JsonSerializable(converters: [MyJsonConverter()])
- class Example {
- //也可以单独指定某一个属性做特殊自定义解释
- //@MyJsonConverter()
- final DateTime property;
- Example(this.property);
- }
- class MyJsonConverter extends JsonConverter<DateTime, String> {
- const MyJsonConverter();
- @override
- DateTime fromJson(String json) {
- return DateTime.parse(json);
- }
- @override
- String toJson(DateTime object) {
- return '';
- }
- }
复制代码
genericArgumentFactories: bool?
- 类型:bool,默认值是 false。
- 描述:针对范型,下面第四块会做介绍利用。
createPerFieldToJson: bool?
- 类型:bool,默认值是 false。
- 描述:会创建一个私有方法 _$ExamplePerFieldToJson 。这个抽象类将为每个属性包罗一个静态函数,从而提供了一种仅对该属性而不是整个对象举行设置的方法。
- @JsonSerializable(createPerFieldToJson: true)
- class DeviceTypeNetModel {
- final num? deviceType;
- final String? deviceTypeName;
- @JsonKey(name: 'num')
- final int? count;
- final DeviceListCountNetModel model;
-
- DeviceTypeNetModel(this.deviceType, this.deviceTypeName, this.count, this.model);
- }
- .g.dart 会多一个内部私有方法
- // ignore: unused_element
- abstract class _$DeviceTypeNetModelPerFieldToJson {
- // ignore: unused_element
- static Object? deviceType(num? instance) => instance;
- // ignore: unused_element
- static Object? deviceTypeName(String? instance) => instance;
- // ignore: unused_element
- static Object? count(int? instance) => instance;
- // ignore: unused_element
- static Object? model(DeviceListCountNetModel instance) => instance;
- }
复制代码
四、范型T
json serializable 在大概两年前发布的v3.5.0版本开始支持泛型,只必要在 @JsonSerializable() 注解中设置genericArgumentFactories为 true,同时必要对 fromJson 和 toJson 方法举行调整,即可支持泛型分析,如下所示:
- @JsonSerializable(genericArgumentFactories: true)
- class Response<T> {
- int status;
- T value;
- factory Response.fromJson(Map<String, dynamic>json, T Function(dynamic json) fromJsonT) => _$ResponseFromJson<T>(json, fromJsonT);
- Map<String, dynamic> toJson(Object? Function(T value) toJsonT) => _$ResponseToJson<T>(this, toJsonT);
- }
- 得到的.g.dart 文件内容如下:
- Response<T> _$ResponseFromJson<T>(
- Map<String, dynamic> json,
- T Function(Object? json) fromJsonT,
- ) =>
- Response<T>(
- (json['status'] as num).toInt(),
- fromJsonT(json['value']),
- );
- Map<String, dynamic> _$ResponseToJson<T>(
- Response<T> instance,
- Object? Function(T value) toJsonT,
- ) =>
- <String, dynamic>{
- 'status': instance.status,
- 'value': toJsonT(instance.value),
- };
复制代码 适用于一些固定结构,可以预处置惩罚一部门业务,其中某个参数根据业务变化在外部处置惩罚业务的场景(接口响应很经典)。
五、摆列
- enum StatusCode {
- @JsonValue(200)
- success,
- @JsonValue(301)
- movedPermanently,
- @JsonValue(302)
- found,
- @JsonValue(500)
- internalServerError,
- }
- @JsonSerializable()
- class BackModel {
- StatusCode code;
- BackModel(this.code);
- factory BackModel.fromJson(Map<String, dynamic> json) =>
- _$BackModelFromJson(json);
- Map<String, dynamic> toJson() => _$BackModelToJson(this);
- }
- 得到的.g.dart 文件内容如下:
- BackModel _$BackModelFromJson(Map<String, dynamic> json) => BackModel(
- $enumDecode(_$StatusCodeEnumMap, json['code'])
- );
- Map<String, dynamic> _$BackModelToJson(BackModel instance) => <String, dynamic>{
- 'code': _$StatusCodeEnumMap[instance.code]!,
- };
- const _$StatusCodeEnumMap = {
- StatusCode.success: 200,
- StatusCode.movedPermanently: 301,
- StatusCode.found: 302,
- StatusCode.internalServerError: 500,
- };
复制代码 或者
- @JsonEnum(valueField: 'code')
- enum StatusCodeEnhanced {
- success(200),
- movedPermanently(301),
- found(302),
- internalServerError(500);
- const StatusCodeEnhanced(this.code);
- final int code;
- }
- @JsonSerializable()
- class BackModel {
- StatusCodeEnhanced status;
- BackModel(this.status);
- factory BackModel.fromJson(Map<String, dynamic> json) =>
- _$BackModelFromJson(json);
- Map<String, dynamic> toJson() => _$BackModelToJson(this);
- }
- 得到的.g.dart 文件内容如下:
- BackModel _$BackModelFromJson(Map<String, dynamic> json) => BackModel(
- $enumDecode(_$StatusCodeEnhancedEnumMap, json['status']),
- );
- Map<String, dynamic> _$BackModelToJson(BackModel instance) => <String, dynamic>{
- 'status': _$StatusCodeEnhancedEnumMap[instance.status]!,
- };
- const _$StatusCodeEnhancedEnumMap = {
- StatusCodeEnhanced.success: 200,
- StatusCodeEnhanced.movedPermanently: 301,
- StatusCodeEnhanced.found: 302,
- StatusCodeEnhanced.internalServerError: 500,
- };
复制代码 摆列记得利用注解unknownEnumValue,以便后续代码健壮性 @JsonKey(unknownEnumValue: Gender.other)
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |