[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fj20uotYBS80sMf-UqKYzN5U2fwvYSrjTAExNN20T6Ps":3},{"code":4,"message":5,"data":6},200,"成功",{"id":7,"createdAt":8,"title":9,"content":10,"summary":11,"image":12,"uid":13,"user":14,"categoryId":21,"category":22,"subCategoryId":24,"subCategory":25,"comments":27,"status":17,"reason":28,"notice":28,"visitCount":29,"commentCount":30,"keywords":31},176,"2026-01-13T10:00:44.931Z","flutter中老生常谈的json序列化操作json_serializable和json_annotation以及插件使用","相信大家在移动端的开发中，不管是iOS还是Android中都有json序列化的操作，比如MJ的json序列化，那么flutter中同样也是有对应的json序列化和反序列化操作。\n\n这里做一个回顾介绍，温故知新一下。\n\n## 一、flutter中的json serializable\n在flutter中需要依赖2个库去实现：\n- json_serializable\n- json_annotation\n\n这2个package需要一起使用，具体的使用可以在对应的pub.dev上看到：\n[https://pub.dev/packages/json_serializable](https://pub.dev/packages/json_serializable)\n[https://pub.dev/packages/json_annotation](https://pub.dev/packages/json_annotation)\n\n具体安装方法：\n```terminal\ndart pub add dev:json_serializable\n```\n\n```terminal\ndart pub add json_annotation\n```\n\n## 二、具体使用\n当我们在请求接口的时候，可以把json数据转成对应的class对象使用。\n比如：\n```user.json\n{\n  \"user_id\" : \"1234\",\n  \"nick_name\" : \"Tom\",\n  \"age\": 1,\n  \"right\": {\n    \"vip\" : 1\n  }\n}\n```\n这里我们使用了嵌套的json结构，即map中还有map结构，所以我们需要定义2个class，然后在user的class中包含right的class，这个是常见的结构形式。\n\n### 2.1 定义Right的class\n```right.dart\nimport 'package:json_annotation/json_annotation.dart';\n\n// 1. 一定要加一个文件引入，这个part引入的.g.dart文件是在后面的dart命令中生成的，而且和class在同一个目录中。\npart 'right.g.dart';\n\n// 2. 需要添加 @JsonSerializable()\n@JsonSerializable()\nclass Right {\n  final int? vip;\n\n  Right({\n    this.vip,\n  });\n\n  // 3. 下面的2个方法需要手动写上，_$RightFromJson和_$RightToJson是在后面的dart命令中生成的，暂时的语法报错，先不要管。（前缀都是默认你的class名字的首字母大写驼峰写法：Right， 后缀统一为fromJson和toJson）\n  factory Right.fromJson(Map\u003CString, dynamic> json) =>\n      _$RightFromJson(json);\n\n  Map\u003CString, dynamic> toJson() => _$RightToJson(this);\n}\n```\n\n### 2.2 定义User的class\n```user.dart\nimport 'package:json_annotation/json_annotation.dart';\nimport 'package:xxx/modules/app/beans/right.dart';\n\n// 1. 声明后续dart命令会生成的文件\npart 'user.g.dart';\n\n// 2. 需要添加 @JsonSerializable()\n@JsonSerializable()\nclass User {\n  // 3. 使用别名，那么要使用@JsonKey去声明原始json中的字段\n  @JsonKey(name: \"user_id\")\n  final String? userId;\n\n  @JsonKey(name: \"nick_name\")\n  final String? nickName;\n\n  final int? age;\n  // 4. 权益class\n  final Right? right;\n\n  User({\n    this.userId,\n    this.nickName,\n    this.age,\n    this.right,\n  });\n\n  // 5. fromJson和toJson方法\n  factory User.fromJson(Map\u003CString, dynamic> json) => _$UserFromJson(json);\n\n  Map\u003CString, dynamic> toJson() => _$UserToJson(this);\n}\n```\n\n### 2.3 json转class\n比如从接口获取到了json数据，然后我们就可以直接使用user class去转化。\n```xxx.dart\n...\nfinal res = response as Map\u003CString, dynamic>?;\nif (res == null) return null;\nfinal user = User.fromJson(res);\n...\n```\n\n### 2.4 执行dart生成命令\n\n以上2个class声明之后，就可以执行dart命令，去生成对应的xxx.g.dart文件。\n\n（终端命令，在根目录下执行，会自动查找所有有@JsonSerializable()的class，然后生成对一个的.g.dart文件）\n```terminal\ndart run build_runner build\n```\n\n以上的基础结构其实已经满足了简单的json序列化操作。\n\n## 三、进阶操作\n### 3.1 在class中声明一个非json字段\n还是用上述的user.dart举例，意思是指，如果在user中增加一个自定义的字段（不在原始json数据中），比如想增加一个是否选中的bool字段：isSelected，那么这个属性就不需要从json中转化。\n\n可以这么做：\n```user.dart\n...\n// 1. 在JsonKey中设置这2个属性为false，表示这个字段不需要从json数据中转，也不需要从class中转的Map中。\n// 2. 这里不用final声明，表示user这个class的isSelected字段可以在使用时进行修改。\n@JsonKey(includeFromJson: false, includeToJson: false)\nbool isSelected = true;\n...\n```\n\n### 3.2 一个class extends 另一个序列化class\n依然拿上面的user.dart举例，现在有一个class，拥有比user class更多的信息，也就是多了一个或者多个字段，然后是在另外一个接口中请求到。\n\n我来详细的举例，比如上面的user，代表的是通用的用户信息，但是现在有一个场景，代表访客，那么这个访客可以有一个访问次数的信息，当然这个访客也拥有通用的用户信息。直接举例：\n```visitor.json\n{\n  \"user_id\" : \"1234\",\n  \"nick_name\" : \"Tom\",\n  \"age\": 1,\n  \"right\": {\n    \"vip\" : 1\n  },\n  # 这里比user信息多一个字段\n  \"visit_count\" : 3\n}\n```\n\n那么visitor应该extendsuser，看下面的代码，我在代码中进行注释。\n```visitor.dart\n// 1. 必须引入user class\nimport 'package:xxx/modules/app/beans/user.dart';\n// 2. 这个文件虽然没有用到right class，但是也必须引入。\n// 否则dart命令将找不到嵌套的right的class声明。\nimport 'package:xxx/modules/app/beans/right.dart';\n\n// 3. 同样需要引入后续命令生成的.g.dart\npart 'visitor.g.dart';\n\n// 4. 这里需要extends user\n@JsonSerializable()\nclass Visitor extends User {\n  @JsonKey(name: \"visit_count\")\n  final int? visitCount;\n\n  Visitor(this.visitCount);\n\n  // 5. 依然需要from json 和 to json方法\n  factory Visitor.fromJson(Map\u003CString, dynamic> json) =>\n      _$VisitorFromJson(json);\n\n  @override\n  Map\u003CString, dynamic> toJson() => _$VisitorToJson(this);\n}\n```\n\n上面的代码解释应该很清晰吧，每次新增一个JsonSerializable的class，都需要执行2.4的dart命令。\n\n### 3.3 使用Android Studio插件\n上面的基本使用大家应该都知道了，但是每次都要写非常多的样式代码，实在是比较费劲，所以有大佬写了Androi Studio插件，提高开发效率。\n![android studio flutter 插件](https://image.xinwei.ltd/image1768298153028.png)\n上面截图中就是快速的json到class的插件，大家可以根据红色框去安装到Android studio中。\n之后，就可以在创建dart文件时，从鼠标菜单中找到它：\n![json to dart menu](https://image.xinwei.ltd/image1768298271244.png)\n\n从下面的截图中，你应该可以知道如何把json数据粘贴到json框中，声明class名称，然后点击生成。\n![json handle png](https://image.xinwei.ltd/image1768298328202.png)\n\n这个插件确实提升了开发效率，大家可以试试。\n\n以上，希望对大家有所帮助。\n","这篇文章介绍一下如何在flutter中做json序列化和反序列化的方案和流程，提高开发效率。","https://image.xinwei.ltd/image1768298153028.png",499668042977349,{"phone":15,"userId":13,"nickName":16,"vipType":17,"avatar":18,"sign":19,"createdAt":20},"13121171998","全栈老韩",1,"https://image.xinwei.ltd/images/IMG_5430.JPG","全栈工程师，擅长iOS App开发、前端（vue、react、nuxt、小程序&Taro）开发、Flutter、React Native、后端（midwayjs、golang、express、koa）开发、docker容器、seo优化等。","2024-01-01T16:14:30.305Z",2,{"id":21,"name":23},"IT技术",11,{"id":24,"name":26,"parentId":21},"Flutter",[],"",80,0,"flutter json_serializable, flutter json_annotation,flutter json, flutter serializable, flutter json annotation, from json, to json, flutter"]