鸿蒙Flutter JSON解析与序列化:json_serializable代码生成详解 概述json_serializable是Flutter生态中最流行的JSON序列化代码生成工具它可以自动生成toJson()和fromJson()方法大大减少手动编写序列化代码的工作量。本文将详细介绍json_serializable的配置、使用方法和高级特性帮助开发者实现自动化序列化。1. json_serializable简介1.1 什么是json_serializablejson_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.02.2 安装依赖flutter pub get2.3 配置build.yaml可选targets:$default:builders:json_serializable:options:explicit_to_json:trueany_map:false3. 基础使用3.1 创建数据模型类importpackage:json_annotation/json_annotation.dart;partweather.g.dart;JsonSerializable()classWeather{finalStringcity;finalint temperature;finalint humidity;Weather({requiredthis.city,requiredthis.temperature,requiredthis.humidity,});factoryWeather.fromJson(MapString,dynamicjson)_$WeatherFromJson(json);MapString,dynamictoJson()_$WeatherToJson(this);}3.2 生成代码运行以下命令生成序列化代码flutter pub run build_runner build常用命令命令说明build单次构建生成代码watch监听文件变化自动重新生成clean清除缓存3.3 生成的代码示例生成的weather.g.dart文件内容Weather_$WeatherFromJson(MapString,dynamicjson)Weather(city:json[city]asString,temperature:json[temperature]asint,humidity:json[humidity]asint,);MapString,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(MapString,dynamicjson)_$WeatherFromJson(json);MapString,dynamictoJson()_$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_jsonJsonSerializable(explicitToJson:true)classWeather{finalWindwind;Weather({requiredthis.wind});}4.2.2 any_mapJsonSerializable(anyMap:true)classWeather{finalStringcity;Weather({requiredthis.city});}4.2.3 fieldRenameJsonSerializable(fieldRename:FieldRename.snake)classWeather{finalStringcityName;// 自动映射为 city_nameWeather({requiredthis.cityName});}FieldRename选项选项说明示例none不转换cityName→cityNamesnake蛇形命名cityName→city_namekebab短横线命名cityName→city-namepascal帕斯卡命名cityName→CityName5. 处理嵌套对象5.1 嵌套对象模型importpackage:json_annotation/json_annotation.dart;partwind.g.dart;JsonSerializable()classWind{finalStringdirection;finalint speed;Wind({requiredthis.direction,requiredthis.speed});factoryWind.fromJson(MapString,dynamicjson)_$WindFromJson(json);MapString,dynamictoJson()_$WindToJson(this);}5.2 在主模型中使用嵌套对象importpackage:json_annotation/json_annotation.dart;importwind.dart;partweather.g.dart;JsonSerializable(explicitToJson:true)classWeather{finalStringcity;finalWindwind;Weather({requiredthis.city,requiredthis.wind});factoryWeather.fromJson(MapString,dynamicjson)_$WeatherFromJson(json);MapString,dynamictoJson()_$WeatherToJson(this);}5.3 处理数组importpackage:json_annotation/json_annotation.dart;importforecast.dart;partweather.g.dart;JsonSerializable(explicitToJson:true)classWeather{finalStringcity;finalListForecastforecast;Weather({requiredthis.city,requiredthis.forecast});factoryWeather.fromJson(MapString,dynamicjson)_$WeatherFromJson(json);MapString,dynamictoJson()_$WeatherToJson(this);}6. 完整示例6.1 数据模型文件weather.dartimportpackage:json_annotation/json_annotation.dart;importwind.dart;importforecast.dart;partweather.g.dart;JsonSerializable(explicitToJson:true,fieldRename:FieldRename.snake)classWeather{finalStringcity;JsonKey(name:temp)finalint temperature;finalint humidity;finalWindwind;finalListForecastforecast;JsonKey(fromJson:_dateTimeFromJson,toJson:_dateTimeToJson)finalDateTimeupdate_time;Weather({requiredthis.city,requiredthis.temperature,requiredthis.humidity,requiredthis.wind,requiredthis.forecast,requiredthis.update_time,});factoryWeather.fromJson(MapString,dynamicjson)_$WeatherFromJson(json);MapString,dynamictoJson()_$WeatherToJson(this);staticDateTime_dateTimeFromJson(Stringjson)DateTime.parse(json);staticString_dateTimeToJson(DateTimedate)date.toIso8601String();}6.2 使用示例importdart:convert;importweather.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 } ;// 反序列化MapString,dynamicjsonDatajsonDecode(jsonString);WeatherweatherWeather.fromJson(jsonData);print(城市:${weather.city});print(温度:${weather.temperature}°C);// 序列化StringencodedjsonEncode(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_serializable的dateTimeFormat配置10. 总结json_serializable是Flutter开发中处理JSON序列化的最佳工具之一通过代码生成大大提高了开发效率和代码质量。掌握其配置和使用方法是每个Flutter开发者的必备技能。下一章将介绍如何处理复杂JSON结构。核心知识点回顾json_serializable通过注解自动生成序列化代码需要在pubspec.yaml中添加json_annotation和json_serializable依赖使用JsonSerializable()注解标记数据模型类使用JsonKey()配置字段映射、默认值、空值处理等使用flutter pub run build_runner build生成代码嵌套对象需要设置explicitToJson: true支持自定义命名风格转换snake_case、kebab-case等生成的代码类型安全编译时检查