【问题标题】:Flutter: How to JSON encode a `List` properly?Flutter:如何正确地对“列表”进行 JSON 编码?
【发布时间】: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

【问题讨论】:

    标签: android ios json http flutter


    【解决方案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_serializablehttps://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
      

      【讨论】:

        猜你喜欢
        • 2021-05-20
        • 2019-07-28
        • 2021-04-21
        • 1970-01-01
        • 2011-03-18
        • 1970-01-01
        • 2011-06-12
        相关资源
        最近更新 更多