Flutter:如何正确地对“列表”进行 JSON 编码?
Posted
技术标签:
【中文标题】Flutter:如何正确地对“列表”进行 JSON 编码?【英文标题】:Flutter: How to JSON encode a `List` properly? 【发布时间】:2020-06-30 14:09:29 【问题描述】:我正在尝试使用 Flutter 通过 REST API 将 List
传递给我的服务器。
下面是代码
Future<void> saveOrderItemList(List<OrderItem> orderItems) async
int responsetag = 0;
try
await http.post("http://url to post the data",
body: convert.json.encode(orderItems.toJson()), //This line do not work
headers:
"Accept": "application/json",
"content-type": "application/json"
).then((http.Response response)
final int statusCode = response.statusCode;
print("RESPONSE: " + response.body);
print("STATUS CODE: " + statusCode.toString());
if (statusCode < 200 || statusCode > 400 || response.body == null)
throw new Exception("Error while fetching data");
else
responsetag = int.parse(response.body);
);
return responsetag;
catch (error)
throw (error);
上面的代码无法运行,因为我无法使用convert.json.encode(orderItems.toJson())
对List
进行编码。
下面是我的OrderItem
bean 及其序列化类的代码。
part 'order_item.g.dart';
/// An annotation for the code generator to know that this class needs the
/// JSON serialization logic to be generated.
@JsonSerializable()
class OrderItem
int idorderItem;
FreshProducts freshProducts;
Order order;
ProductSize productSize;
double orderItemExpectedPricePerKg;
double orderItemQuantity;
int dateCreated;
int lastUpdated;
OrderItem(
this.idorderItem,
this.freshProducts,
this.order,
this.productSize,
this.orderItemExpectedPricePerKg,
this.orderItemQuantity,
this.dateCreated,
this.lastUpdated
);
/// A necessary factory constructor for creating a new User instance
/// from a map. Pass the map to the generated `_$OrderItemFromJson()` constructor.
/// The constructor is named after the source class, in this case User.
factory OrderItem.fromJson(Map<String, dynamic> json) => _$OrderItemFromJson(json);
/// `toJson` is the convention for a class to declare support for serialization
/// to JSON. The implementation simply calls the private, generated
/// helper method `_$OrderItemToJson`.
Map<String, dynamic> toJson() => _$OrderItemToJson(this);
和
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'order_item.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
OrderItem _$OrderItemFromJson(Map<String, dynamic> json)
return OrderItem(
idorderItem: json['idorderItem'] as int,
freshProducts: json['freshProducts'] == null
? null
: FreshProducts.fromJson(json['freshProducts'] as Map<String, dynamic>),
order: json['order'] == null
? null
: Order.fromJson(json['order'] as Map<String, dynamic>),
productSize: json['productSize'] == null
? null
: ProductSize.fromJson(json['productSize'] as Map<String, dynamic>),
orderItemExpectedPricePerKg:
(json['orderItemExpectedPricePerKg'] as num)?.toDouble(),
orderItemQuantity: (json['orderItemQuantity'] as num)?.toDouble(),
dateCreated: json['dateCreated'] as int,
lastUpdated: json['lastUpdated'] as int,
);
Map<String, dynamic> _$OrderItemToJson(OrderItem instance) => <String, dynamic>
'idorderItem': instance.idorderItem,
'freshProducts': instance.freshProducts,
'order': instance.order,
'productSize': instance.productSize,
'orderItemExpectedPricePerKg': instance.orderItemExpectedPricePerKg,
'orderItemQuantity': instance.orderItemQuantity,
'dateCreated': instance.dateCreated,
'lastUpdated': instance.lastUpdated,
;
如何确保我可以将列表从颤振 http 传递给 POST
?
【问题讨论】:
【参考方案1】:我解决了类似的问题。但是我的 List
是用其他键包裹的,例如 "data":listOfItemJson
。所以我首先创建了一个Map
,就像var map = "data": MainOrderController.orderModel.toJson();
,当我发布这个url时,我更新了发布机制,比如:
var response =
await http.post(url, headers: headers, body: jsonEncode(map));
注意:jsonEncode()
是 import 'dart:convert';
包的一部分。
我希望你能得到一个想法
【讨论】:
在您的问题中,您提到您正在使用convert.json.encode(orderItems.toJson())
,但我想告诉您,我曾经将项目列表首先转换为地图。而且这个map也是json的字符串格式。我将列表转换为地图,因为我的帖子参数需要包装 json。然后我使用 jsonEncode() 方法对地图进行结束编码。 因此您可以尝试使用 jsonEndcode() 对列表进行编码
使用我的代码,你能给我一个例子吗?【参考方案2】:
我对此的看法是用https://github.com/k-paxian/dart-json-mapper 替换json_serializable
库
这很相似,但不要用样板文件过度膨胀你的代码,也不要强迫你维护大量的 '*.g.part' 文件等。
它不仅可以帮助您解决这种情况,还可以帮助您解决所有 Dart Object => JSON => Dart Object 的情况。
请先仔细阅读库自述文件,尤其是“基本设置”部分。
使用dart-json-mapper
,您的代码可能如下所示:
import 'main.reflectable.dart' show initializeReflectable;
import 'package:dart_json_mapper/dart_json_mapper.dart' show jsonSerializable, JsonMapper;
@jsonSerializable
@Json(enumValues: ProductSize.values)
enum ProductSize Big, Small
@jsonSerializable
class Order
// ...
@jsonSerializable
class FreshProducts
// ...
@jsonSerializable
class OrderItem
int idorderItem;
FreshProducts freshProducts;
Order order;
ProductSize productSize;
double orderItemExpectedPricePerKg;
double orderItemQuantity;
int dateCreated;
int lastUpdated;
OrderItem(
this.idorderItem,
this.freshProducts,
this.order,
this.productSize,
this.orderItemExpectedPricePerKg,
this.orderItemQuantity,
this.dateCreated,
this.lastUpdated
);
void main
initializeReflectable();
final orderItems = <OrderItem>[OrderItem(), OrderItem(), OrderItem()];
// Instead of convert.json.encode(orderItems.toJson())
final orderItemsJson = JsonMapper.serialize(orderItems);
// orderItemsJson will have Json string which you could pass as body to your post request
【讨论】:
【参考方案3】:根据json_serializable和https://github.com/google/json_serializable.dart/issues/651,可以将以下内容放到根目录下的build.yaml中。 explicit_to_json 默认为 false,设置为 true 会显式调用嵌套的 toJson。
targets:
$default:
builders:
json_serializable:
options:
# Options configure how source code is generated for every
# `@JsonSerializable`-annotated class in the package.
#
# The default value for each is listed.
explicit_to_json: true
【讨论】:
以上是关于Flutter:如何正确地对“列表”进行 JSON 编码?的主要内容,如果未能解决你的问题,请参考以下文章
Flutter DistanceMatrix JSON 无法正确解析
在 Flutter 中使用 ListView 从 API 检索 json 对象列表时。拥有有状态或无状态小部件是不是正确?