news 2026/7/23 3:20:57

鸿蒙Flutter JSON解析与序列化:json_serializable代码生成详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
鸿蒙Flutter JSON解析与序列化:json_serializable代码生成详解




概述

json_serializable是Flutter生态中最流行的JSON序列化代码生成工具,它可以自动生成toJson()fromJson()方法,大大减少手动编写序列化代码的工作量。本文将详细介绍json_serializable的配置、使用方法和高级特性,帮助开发者实现自动化序列化。

1. json_serializable简介

1.1 什么是json_serializable

json_serializable是一个Dart代码生成包,通过注解标记数据模型类,自动生成序列化和反序列化代码。

1.2 核心优势

  • 减少重复代码:自动生成toJson()fromJson()方法
  • 类型安全:编译时检查类型转换
  • 减少错误:避免手动编写时的拼写和类型错误
  • 易于维护:数据模型变更时自动更新转换代码

1.3 工作原理

数据模型类(带注解) → build_runner → 生成.g.dart文件 → 编译使用

2. 安装与配置

2.1 添加依赖

pubspec.yaml中添加以下依赖:

dependencies:json_annotation:^4.8.1dev_dependencies:build_runner:^2.4.6json_serializable:^6.7.0

2.2 安装依赖

flutter pub get

2.3 配置build.yaml(可选)

targets:$default:builders:json_serializable:options:explicit_to_json:trueany_map:false

3. 基础使用

3.1 创建数据模型类

import'package:json_annotation/json_annotation.dart';part'weather.g.dart';@JsonSerializable()classWeather{finalStringcity;finalint temperature;finalint humidity;Weather({requiredthis.city,requiredthis.temperature,requiredthis.humidity,});factoryWeather.fromJson(Map<String,dynamic>json)=>_$WeatherFromJson(json);Map<String,dynamic>toJson()=>_$WeatherToJson(this);}

3.2 生成代码

运行以下命令生成序列化代码:

flutter pub run build_runner build

常用命令:

命令说明
build单次构建,生成代码
watch监听文件变化,自动重新生成
clean清除缓存

3.3 生成的代码示例

生成的weather.g.dart文件内容:

Weather_$WeatherFromJson(Map<String,dynamic>json)=>Weather(city:json['city']asString,temperature:json['temperature']asint,humidity:json['humidity']asint,);Map<String,dynamic>_$WeatherToJson(Weatherinstance)=><String,dynamic>{'city':instance.city,'temperature':instance.temperature,'humidity':instance.humidity,};

4. 高级注解配置

4.1 @JsonKey注解

4.1.1 重命名字段
@JsonSerializable()classWeather{@JsonKey(name:'city_name')finalStringcity;@JsonKey(name:'temp')finalint temperature;Weather({requiredthis.city,requiredthis.temperature});factoryWeather.fromJson(Map<String,dynamic>json)=>_$WeatherFromJson(json);Map<String,dynamic>toJson()=>_$WeatherToJson(this);}
4.1.2 忽略字段
@JsonSerializable()classWeather{finalStringcity;@JsonKey(ignore:true)finalString?internalId;Weather({requiredthis.city,this.internalId});}
4.1.3 指定默认值
@JsonSerializable()classWeather{finalStringcity;@JsonKey(defaultValue:0)finalint temperature;Weather({requiredthis.city,requiredthis.temperature});}
4.1.4 处理空值
@JsonSerializable()classWeather{@JsonKey(nullable:false)finalStringcity;@JsonKey(nullable:true)finalString?description;Weather({requiredthis.city,this.description});}
4.1.5 自定义转换函数
@JsonSerializable()classWeather{finalStringcity;@JsonKey(fromJson:_dateTimeFromJson,toJson:_dateTimeToJson)finalDateTimeupdateTime;Weather({requiredthis.city,requiredthis.updateTime});staticDateTime_dateTimeFromJson(Stringjson)=>DateTime.parse(json);staticString_dateTimeToJson(DateTimedate)=>date.toIso8601String();}

4.2 @JsonSerializable注解配置

4.2.1 explicit_to_json
@JsonSerializable(explicitToJson:true)classWeather{finalWindwind;Weather({requiredthis.wind});}
4.2.2 any_map
@JsonSerializable(anyMap:true)classWeather{finalStringcity;Weather({requiredthis.city});}
4.2.3 fieldRename
@JsonSerializable(fieldRename:FieldRename.snake)classWeather{finalStringcityName;// 自动映射为 city_nameWeather({requiredthis.cityName});}

FieldRename选项:

选项说明示例
none不转换cityNamecityName
snake蛇形命名cityNamecity_name
kebab短横线命名cityNamecity-name
pascal帕斯卡命名cityNameCityName

5. 处理嵌套对象

5.1 嵌套对象模型

import'package:json_annotation/json_annotation.dart';part'wind.g.dart';@JsonSerializable()classWind{finalStringdirection;finalint speed;Wind({requiredthis.direction,requiredthis.speed});factoryWind.fromJson(Map<String,dynamic>json)=>_$WindFromJson(json);Map<String,dynamic>toJson()=>_$WindToJson(this);}

5.2 在主模型中使用嵌套对象

import'package:json_annotation/json_annotation.dart';import'wind.dart';part'weather.g.dart';@JsonSerializable(explicitToJson:true)classWeather{finalStringcity;finalWindwind;Weather({requiredthis.city,requiredthis.wind});factoryWeather.fromJson(Map<String,dynamic>json)=>_$WeatherFromJson(json);Map<String,dynamic>toJson()=>_$WeatherToJson(this);}

5.3 处理数组

import'package:json_annotation/json_annotation.dart';import'forecast.dart';part'weather.g.dart';@JsonSerializable(explicitToJson:true)classWeather{finalStringcity;finalList<Forecast>forecast;Weather({requiredthis.city,requiredthis.forecast});factoryWeather.fromJson(Map<String,dynamic>json)=>_$WeatherFromJson(json);Map<String,dynamic>toJson()=>_$WeatherToJson(this);}

6. 完整示例

6.1 数据模型文件

weather.dart:

import'package:json_annotation/json_annotation.dart';import'wind.dart';import'forecast.dart';part'weather.g.dart';@JsonSerializable(explicitToJson:true,fieldRename:FieldRename.snake)classWeather{finalStringcity;@JsonKey(name:'temp')finalint temperature;finalint humidity;finalWindwind;finalList<Forecast>forecast;@JsonKey(fromJson:_dateTimeFromJson,toJson:_dateTimeToJson)finalDateTimeupdate_time;Weather({requiredthis.city,requiredthis.temperature,requiredthis.humidity,requiredthis.wind,requiredthis.forecast,requiredthis.update_time,});factoryWeather.fromJson(Map<String,dynamic>json)=>_$WeatherFromJson(json);Map<String,dynamic>toJson()=>_$WeatherToJson(this);staticDateTime_dateTimeFromJson(Stringjson)=>DateTime.parse(json);staticString_dateTimeToJson(DateTimedate)=>date.toIso8601String();}

6.2 使用示例

import'dart:convert';import'weather.dart';voidmain(){StringjsonString=''' { "city": "北京", "temp": 28, "humidity": 65, "wind": {"direction": "东南风", "speed": 3}, "forecast": [ {"date": "周一", "high": 30, "low": 22}, {"date": "周二", "high": 29, "low": 21} ], "update_time": "2024-07-22T14:30:00" } ''';// 反序列化Map<String,dynamic>jsonData=jsonDecode(jsonString);Weatherweather=Weather.fromJson(jsonData);print('城市:${weather.city}');print('温度:${weather.temperature}°C');// 序列化Stringencoded=jsonEncode(weather);print('\n序列化结果:$encoded');}

7. 与手动序列化的对比

特性手动序列化json_serializable
代码量少(仅需定义模型)
错误率低(编译时检查)
开发效率
维护成本
灵活性
学习成本

8. 鸿蒙平台兼容性

8.1 依赖版本选择

确保使用与Flutter版本兼容的json_serializable版本。

8.2 代码生成

代码生成在开发机器上完成,生成的.g.dart文件会被打包到应用中,鸿蒙平台运行时无需额外处理。

8.3 性能考虑

生成的代码与手动编写的代码性能相当,不会影响鸿蒙平台的运行效率。

9. 常见问题与解决方案

9.1 生成代码失败

问题:运行build_runner时出错

解决方案

  • 确保所有依赖已正确安装
  • 检查注解是否正确
  • 运行flutter pub run build_runner clean清除缓存后重试

9.2 字段不匹配

问题:JSON字段名与Dart字段名不同

解决方案

  • 使用@JsonKey(name: 'json_field_name')重命名
  • 使用fieldRename配置自动转换命名风格

9.3 嵌套对象序列化失败

问题:嵌套对象没有正确序列化

解决方案

  • @JsonSerializable()中设置explicitToJson: true
  • 确保嵌套对象也使用了@JsonSerializable()注解

9.4 DateTime类型处理

问题:DateTime类型无法直接序列化

解决方案

  • 使用@JsonKey(fromJson: ..., toJson: ...)自定义转换函数
  • 使用json_serializabledateTimeFormat配置

10. 总结

json_serializable是Flutter开发中处理JSON序列化的最佳工具之一,通过代码生成大大提高了开发效率和代码质量。掌握其配置和使用方法是每个Flutter开发者的必备技能。下一章将介绍如何处理复杂JSON结构。

核心知识点回顾

  1. json_serializable通过注解自动生成序列化代码
  2. 需要在pubspec.yaml中添加json_annotationjson_serializable依赖
  3. 使用@JsonSerializable()注解标记数据模型类
  4. 使用@JsonKey()配置字段映射、默认值、空值处理等
  5. 使用flutter pub run build_runner build生成代码
  6. 嵌套对象需要设置explicitToJson: true
  7. 支持自定义命名风格转换(snake_case、kebab-case等)
  8. 生成的代码类型安全,编译时检查
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/23 3:20:25

TM4C123BH6ZRB PWM故障保护与QEI编码器接口实战配置详解

1. 项目概述与核心价值在电机控制、工业自动化或者机器人关节驱动这类嵌入式应用里&#xff0c;我们工程师最头疼的两件事是什么&#xff1f;一是“输出要准”&#xff0c;二是“安全要稳”。输出不准&#xff0c;电机要么转不动&#xff0c;要么乱转&#xff1b;安全不稳&…

作者头像 李华
网站建设 2026/7/23 3:18:38

LangGraph入门

LangGraph入门很简陋的入门状态&#xff0c;第一部分LangGraph 本质上是一个低层的 Agent 编排与运行框架&#xff0c;重点不是“帮你写 Prompt”&#xff0c;而是管理状态、流程、持久化、流式输出和人工介入 模型 → 工具 → 模型 → 工具 → 模型 → END,实际上是一个循环1.…

作者头像 李华
网站建设 2026/7/23 3:15:56

RabbitMQ核心原理与应用实践:从消息中间件到分布式系统解耦

1. RabbitMQ 核心定位与核心价值RabbitMQ 是一款成熟稳定的开源消息代理和流处理中间件&#xff0c;采用 Erlang 语言开发&#xff0c;遵循 Mozilla Public License 2.0 开源协议。作为分布式系统中消息通信的基础设施&#xff0c;它通过高效的消息路由机制实现了生产者和消费者…

作者头像 李华
网站建设 2026/7/23 3:14:13

FastAPI连接MySQL实现自动建表

1. 启动本地MySQL服务Shell 终端输入&#xff1a;net start mysql80 &#xff0c;先启动MySQL服务Shell 终端输入&#xff1a;mysql -u root -p &#xff0c;然后输入密码&#xff0c;进入MySQL数据库Shell 终端输入&#xff1a;net stop mysql80 &#xff0c;关闭MySQL服务She…

作者头像 李华
网站建设 2026/7/23 3:14:04

2026年盘锦大米十大靠谱厂家排名,你选对了吗?

在消费升级的背景下&#xff0c;消费者对大米品质的要求日益提升。盘锦大米作为我国优质粳米的代表&#xff0c;凭借其得天独厚的生长环境和独特口感&#xff0c;一直备受市场青睐。然而&#xff0c;随着市场需求的增长&#xff0c;盘锦大米加工企业数量众多&#xff0c;质量参…

作者头像 李华