如何在Dart中生成自定义JSON?基于指定模型生成特定格式JSON的技术问询
自定义JSON序列化方案:将Dart Book实例转换为指定格式
要生成你需要的这种特殊结构的JSON,因为它的键名采用了带数组下标(如routes[0][address])和下划线命名(如rate_id)的格式,没法直接用Dart默认的json_serializable或者jsonEncode生成,我们可以手动构建对应的键值对Map,再序列化为JSON。
实现步骤与代码
首先,我们给Dart类添加构造函数(方便实例初始化),然后编写核心转换方法,把Book实例映射成目标格式的Map:
import 'dart:convert'; class Book { List<Route> routes; double distance; int rateId; List<int> optionsIds; String comment; int regionId; // 命名构造函数,简化实例初始化 Book({ required this.routes, required this.distance, required this.rateId, required this.optionsIds, required this.comment, required this.regionId, }); } class Route { double lat; double lng; int order; String address; // 命名构造函数 Route({ required this.lat, required this.lng, required this.order, required this.address, }); } // 核心转换方法:将Book实例转为目标格式的Map Map<String, dynamic> convertBookToCustomMap(Book book) { final result = <String, dynamic>{}; // 处理routes列表,生成带索引的键值对 for (int i = 0; i < book.routes.length; i++) { final route = book.routes[i]; result['routes[$i][address]'] = route.address; result['routes[$i][lat]'] = route.lat; result['routes[$i][lng]'] = route.lng; result['routes[$i][order]'] = route.order; } // 处理普通字段,转换键名格式 result['distance'] = book.distance; result['rate_id'] = book.rateId; result['comment'] = book.comment; result['region_id'] = book.regionId; // 处理optionsIds列表 // 注意:标准JSON不允许重复键名,用jsonEncode序列化后最后一个值会覆盖前面的 // 如果是模拟表单多值提交,建议直接生成form data字符串而非JSON for (final id in book.optionsIds) { result['option_ids[]'] = id; } return result; } // 测试代码 void main() { var book = Book( routes: [ Route(lat: 12, lng: 12, order: 0, address: 'address1'), Route(lat: 12, lng: 12, order: 1, address: 'address2'), ], distance: 10.3, rateId: 0, optionsIds: [1,2], comment: 'book comment', regionId: 1, ); // 转换为Map后序列化为JSON final customJson = jsonEncode(convertBookToCustomMap(book)); print(customJson); }
关键注意事项
- 重复键名的问题:你提供的目标JSON中包含重复的
option_ids[]键,但标准JSON规范不允许重复键名,使用jsonEncode序列化后,最后一个值会覆盖前面的。如果实际需求是模拟HTML表单的多值提交格式(比如option_ids[]=1&option_ids[]=2),建议直接生成form data字符串,而非严格的JSON。 - 自定义键名的灵活性:通过手动构建Map,我们可以精准控制每个字段的键名格式,比如把驼峰命名的
rateId转换为下划线命名的rate_id,或者生成带索引的routes键,完全匹配你的需求格式。
内容的提问来源于stack exchange,提问作者Akbar Pulatov
相关产品推荐
相关产品推荐

