IT评测·应用市场-qidao123.com

标题: [Flutter]Json序列化json_serializable利用属性全介绍 [打印本页]

作者: 傲渊山岳    时间: 2025-1-21 18:33
标题: [Flutter]Json序列化json_serializable利用属性全介绍
联合上一篇介绍[Flutter]Json和序列化数据,看欣赏关注的人还是许多。这里出一篇详细介绍json_serializable的属性参数的分析阐明。此文章根据现在最新版本json_serializable: ^6.9.0介绍 ,下面开始:
一、一般利用介绍

  1. // json_serializable模型写法示意
  2. import 'package:json_annotation/json_annotation.dart';
  3. //当前文件名+.g.dart
  4. part 'device_model.g.dart';
  5. //添加注解
  6. @JsonSerializable()
  7. class DeviceTypeNetModel {
  8.   final num? deviceType;
  9.   final String? deviceTypeName;
  10.   //自定义一些属性的某些设置
  11.   @JsonKey(name: 'num')
  12.   final int? count;
  13. //构造函数
  14.   DeviceTypeNetModel(this.deviceType, this.deviceTypeName, this.count);
  15. //工厂构造函数fromJson(也可以不写,需要配置对应的设置)
  16.   factory DeviceTypeNetModel.fromJson(Map<String, dynamic> json) =>
  17.       _$DeviceTypeNetModelFromJson(json);
  18. //转json (也可以不写,需要配置对应的设置)
  19.   Map<String, dynamic> toJson() => _$DeviceTypeNetModelToJson(this);
  20. }
复制代码
二、JsonKey参数分析


defaultValue:Object?


  1. @JsonKey(defaultValue: 'Unknown')
  2. final String name;
复制代码
如果 JSON 数据中没有 name 字段,默认值 Unknown 会被利用。

disallowNullValue:bool?


  1. @JsonKey(disallowNullValue: true)
  2. final String name;
复制代码
如果 name 字段为 null,在序列化时将抛堕落误。

fromJson 和 toJson : Function?


  1. @JsonKey(fromJson: _fromJson, toJson: _toJson)
  2. final DateTime timestamp;
  3. static DateTime _fromJson(String timestamp) {
  4.   return DateTime.parse(timestamp);
  5. }
  6. static String _toJson(DateTime timestamp) {
  7.   return timestamp.toIso8601String();
  8. }
复制代码
这里,timestamp 字段会利用自定义的 fromJson 和 toJson 方法举行分析和序列化。

name: String?


  1. @JsonKey(name: 'full_name')
  2. final String name;
复制代码
在上面的示例中,name 字段会被序列化为 full_name,而不是默认的 name。


includeFromJson 和 includeToJson : bool?


  1. @JsonKey(includeFromJson: true,includeToJson: true)
  2. final String temporaryData;
复制代码
这里,temporaryData 字段将不会出现在天生的 JSON 中,而且也不会到场 fromJson 过程。


includeIfNull:bool?


  1. @JsonKey(includeIfNull: false)
  2. final String? email;
复制代码
如果 email 字段为 null,它将不会出现在天生的 JSON 中。


readValue: Object? Function(Map,Srting)?


  1. @JsonKey(readValue: NormalTool.transFromMill)
  2. final String timeMill;
  3. class NormalTool {
  4.   static String transFromMill(Map p0, String p1) {
  5.     return p0[p1].toString();
  6.   }
  7. }
复制代码
//留意这里转化基本类型可以,但是如果是DateTime类型会出现不属于基本类型的转化toJson会被定义为String,进而影响fromJson的转化。
比方上述的如果转化为DateTime,得到的.g.dart的转化内容如下:
  1. DeviceTypeNetModel _$DeviceTypeNetModelFromJson(Map<String, dynamic> json) =>
  2.     DeviceTypeNetModel(
  3.       DateTime.parse(NormalTool.transFromMill(json, 'timeMill') as String),
  4.     );
  5. Map<String, dynamic> _$DeviceTypeNetModelToJson(DeviceTypeNetModel instance) =>
  6.     <String, dynamic>{
  7.       'timeMill': instance.timeMill.toIso8601String(),
  8.     };
复制代码


required:bool?


  1. @JsonKey(required: true)
  2. final String name;
复制代码
这意味着,name 字段在 JSON 中是必须存在的,否则分析时会抛出非常。

unknownEnumValue : Enum?


  1. @JsonKey(unknownEnumValue: Gender.other)
  2. final Gender gender;
复制代码
如果 JSON 中的 gender 字段值不是摆列中定义的 male、female,则默认利用 Gender.other。

三、JsonSerializable参数分析


anyMap:bool?


  1. @JsonSerializable(anyMap: true)
  2. class User {
  3.   final String name;
  4.   User({required this.name});
  5. }
复制代码

checked: bool?


  1. @JsonSerializable(checked: true)
  2. class User {
  3.   final String name;
  4.   User({required this.name});
  5. }
复制代码

constructor: String?


  1. @JsonSerializable(constructor: 'customConstructor')
  2. class User {
  3.   final String name;
  4.   User.customConstructor({required this.name});
  5. }
复制代码
在这个例子中,User 类会利用 customConstructor 来天生实例。

createFieldMap: bool?


  1. @JsonSerializable(createFieldMap: true)
  2. class DeviceTypeNetModel {
  3.   final num? deviceType;
  4.   final String? deviceTypeName;
  5.   @JsonKey(name: 'num')
  6.   final int? count;
  7.   final DeviceListCountNetModel model;
  8.   
  9.   DeviceTypeNetModel(this.deviceType, this.deviceTypeName, this.count, this.model);
  10.   
  11.   Map<String, String> fieldMap() => _$DeviceTypeNetModelFieldMap;
  12. }
  13. .g.dart 会多一个内部私有方法
  14. const _$DeviceTypeNetModelFieldMap = <String, String>{
  15.   'deviceType': 'deviceType',
  16.   'deviceTypeName': 'deviceTypeName',
  17.   'count': 'num',
  18.   'model': 'model',
  19. };
复制代码

createJsonKeys: bool?


  1. @JsonSerializable(createJsonKeys: true)
  2. class DeviceTypeNetModel {
  3.   final num? deviceType;
  4.   final String? deviceTypeName;
  5.   @JsonKey(name: 'num')
  6.   final int? count;
  7.   final DeviceListCountNetModel model;
  8.   
  9.   DeviceTypeNetModel(this.deviceType, this.deviceTypeName, this.count, this.model);
  10. }
  11. .g.dart 会多一个内部私有方法
  12. abstract final class _$DeviceTypeNetModelJsonKeys {
  13.   static const String deviceType = 'deviceType';
  14.   static const String deviceTypeName = 'deviceTypeName';
  15.   static const String count = 'num';
  16.   static const String model = 'model';
  17. }
复制代码

createFactory: bool?



  1. @JsonSerializable(createFactory: false)
  2. class User {
  3.   final String name;
  4.   User({required this.name});
  5.   // 手动定义 fromJson 方法
  6.   static User fromJson(Map<String, dynamic> json) {
  7.     return User(name: json['name']);
  8.   }
  9. }
复制代码

createToJson: bool?


  1. @JsonSerializable(createToJson: false)
  2. class User {
  3.   final String name;
  4.   User({required this.name});
  5.   // 手动定义 toJson 方法
  6.   Map<String, dynamic> toJson() {
  7.     return {'name': name};
  8.   }
复制代码

disallowUnrecognizedKeys: bool?



explicitToJson: bool?



  1. @JsonSerializable(explicitToJson: true)
  2. class User {
  3.   final String name;
  4.   final Address address;
  5.   User({required this.name, required this.address});
  6.   factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
  7.   Map<String, dynamic> toJson() => _$UserToJson(this);
  8. }
  9. @JsonSerializable()
  10. class Address {
  11.   final String city;
  12.   final String street;
  13.   Address({required this.city, required this.street});
  14.   factory Address.fromJson(Map<String, dynamic> json) => _$AddressFromJson(json);
  15.   Map<String, dynamic> toJson() => _$AddressToJson(this);
  16. }
复制代码
在这个例子中,User 类会显式调用 Address 类的 toJson,而不依赖于 json_serializable 的递归主动处置惩罚。

fieldRename: FieldRename?


  1. @JsonSerializable(fieldRename: FieldRename.snake)
  2. class User {
  3.   final String firstName;
  4.   final String lastName;
  5.   User({required this.firstName, required this.lastName});
  6. }
复制代码
在这个例子中,firstName 会被转换为 first_name,lastName 会被转换为 last_name。

ignoreUnannotated: bool?


  1. @JsonSerializable(ignoreUnannotated: true)
  2. class User {
  3.   final String name;
  4.   @JsonKey(name: 'age_in_years')
  5.   final int age;
  6.   User({required this.name, required this.age});
  7. }
复制代码
如果你设置了 ignoreUnannotated: true,name 字段不会被包罗在天生的 toJson 和 fromJson 方法中,只有 age 字段会被序列化。

includeIfNull: bool?



converters: List?


  1. @JsonSerializable(converters: [MyJsonConverter()])
  2. class Example {
  3. //也可以单独指定某一个属性做特殊自定义解释
  4. //@MyJsonConverter()
  5.   final DateTime property;
  6.   Example(this.property);
  7. }
  8. class MyJsonConverter extends JsonConverter<DateTime, String> {
  9.   const MyJsonConverter();
  10.   @override
  11.   DateTime fromJson(String json) {
  12.     return DateTime.parse(json);
  13.   }
  14.   @override
  15.   String toJson(DateTime object) {
  16.     return '';
  17.   }
  18. }
复制代码

genericArgumentFactories: bool?



createPerFieldToJson: bool?


  1. @JsonSerializable(createPerFieldToJson: true)
  2. class DeviceTypeNetModel {
  3.   final num? deviceType;
  4.   final String? deviceTypeName;
  5.   @JsonKey(name: 'num')
  6.   final int? count;
  7.   final DeviceListCountNetModel model;
  8.   
  9.   DeviceTypeNetModel(this.deviceType, this.deviceTypeName, this.count, this.model);
  10. }
  11. .g.dart 会多一个内部私有方法
  12. // ignore: unused_element
  13. abstract class _$DeviceTypeNetModelPerFieldToJson {
  14.   // ignore: unused_element
  15.   static Object? deviceType(num? instance) => instance;
  16.   // ignore: unused_element
  17.   static Object? deviceTypeName(String? instance) => instance;
  18.   // ignore: unused_element
  19.   static Object? count(int? instance) => instance;
  20.   // ignore: unused_element
  21.   static Object? model(DeviceListCountNetModel instance) => instance;
  22. }
复制代码

四、范型T

json serializable 在大概两年前发布的v3.5.0版本开始支持泛型,只必要在 @JsonSerializable() 注解中设置genericArgumentFactories为 true,同时必要对 fromJson 和 toJson 方法举行调整,即可支持泛型分析,如下所示:
  1. @JsonSerializable(genericArgumentFactories: true)
  2. class Response<T> {
  3. int status;
  4. T value;
  5. factory Response.fromJson(Map<String, dynamic>json, T Function(dynamic json) fromJsonT) => _$ResponseFromJson<T>(json, fromJsonT);
  6. Map<String, dynamic> toJson(Object? Function(T value) toJsonT) => _$ResponseToJson<T>(this, toJsonT);
  7. }
  8. 得到的.g.dart 文件内容如下:
  9. Response<T> _$ResponseFromJson<T>(
  10.   Map<String, dynamic> json,
  11.   T Function(Object? json) fromJsonT,
  12. ) =>
  13.     Response<T>(
  14.       (json['status'] as num).toInt(),
  15.       fromJsonT(json['value']),
  16.     );
  17. Map<String, dynamic> _$ResponseToJson<T>(
  18.   Response<T> instance,
  19.   Object? Function(T value) toJsonT,
  20. ) =>
  21.     <String, dynamic>{
  22.       'status': instance.status,
  23.       'value': toJsonT(instance.value),
  24.     };
复制代码
适用于一些固定结构,可以预处置惩罚一部门业务,其中某个参数根据业务变化在外部处置惩罚业务的场景(接口响应很经典)。

五、摆列

  1. enum StatusCode {
  2.   @JsonValue(200)
  3.   success,
  4.   @JsonValue(301)
  5.   movedPermanently,
  6.   @JsonValue(302)
  7.   found,
  8.   @JsonValue(500)
  9.   internalServerError,
  10. }
  11. @JsonSerializable()
  12. class BackModel {
  13.   StatusCode code;
  14.   BackModel(this.code);
  15.   factory BackModel.fromJson(Map<String, dynamic> json) =>
  16.       _$BackModelFromJson(json);
  17.   Map<String, dynamic> toJson() => _$BackModelToJson(this);
  18. }
  19. 得到的.g.dart 文件内容如下:
  20. BackModel _$BackModelFromJson(Map<String, dynamic> json) => BackModel(
  21.       $enumDecode(_$StatusCodeEnumMap, json['code'])
  22.     );
  23. Map<String, dynamic> _$BackModelToJson(BackModel instance) => <String, dynamic>{
  24.       'code': _$StatusCodeEnumMap[instance.code]!,
  25.     };
  26. const _$StatusCodeEnumMap = {
  27.   StatusCode.success: 200,
  28.   StatusCode.movedPermanently: 301,
  29.   StatusCode.found: 302,
  30.   StatusCode.internalServerError: 500,
  31. };
复制代码
或者
  1. @JsonEnum(valueField: 'code')
  2. enum StatusCodeEnhanced {
  3.   success(200),
  4.   movedPermanently(301),
  5.   found(302),
  6.   internalServerError(500);
  7.   const StatusCodeEnhanced(this.code);
  8.   final int code;
  9. }
  10. @JsonSerializable()
  11. class BackModel {
  12.   StatusCodeEnhanced status;
  13.   BackModel(this.status);
  14.   factory BackModel.fromJson(Map<String, dynamic> json) =>
  15.       _$BackModelFromJson(json);
  16.   Map<String, dynamic> toJson() => _$BackModelToJson(this);
  17. }
  18. 得到的.g.dart 文件内容如下:
  19. BackModel _$BackModelFromJson(Map<String, dynamic> json) => BackModel(
  20.       $enumDecode(_$StatusCodeEnhancedEnumMap, json['status']),
  21.     );
  22. Map<String, dynamic> _$BackModelToJson(BackModel instance) => <String, dynamic>{
  23.       'status': _$StatusCodeEnhancedEnumMap[instance.status]!,
  24.     };
  25. const _$StatusCodeEnhancedEnumMap = {
  26.   StatusCodeEnhanced.success: 200,
  27.   StatusCodeEnhanced.movedPermanently: 301,
  28.   StatusCodeEnhanced.found: 302,
  29.   StatusCodeEnhanced.internalServerError: 500,
  30. };
复制代码
摆列记得利用注解unknownEnumValue,以便后续代码健壮性 @JsonKey(unknownEnumValue: Gender.other)

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/) Powered by Discuz! X3.4