如何从多部分/表单数据响应中提取数据?

Posted

技术标签:

【中文标题】如何从多部分/表单数据响应中提取数据?【英文标题】:How to extract data from a multipart/form-data response? 【发布时间】:2022-01-07 12:26:22 【问题描述】:

我正在使用内容类型为 multipart/form-data 的 POST 方法将图像上传到 storageAPI。该 api 返回一个如下所示的对象响应:


"id": "6d50c066-cf65-4748-8b9a-183c3526f49b",
"name": "hotel_6.jpg",
"fileKey": "lv/im/5d9feb8e-2ea8-439d-a550-1e937081e085-hotel_6.jpg",
"fileExtension": ".jpg",
"mimeType": "image/jpeg",
"catalogueUrl": 
    "mainUrl": "https://xy.abc.com/lv/im/5d9feb8e-2ea8-439d-a550-1e937081e085-hotel_6.jpg",
    "thumbnailUrls": []
,
"createdAt": "2021-11-25T06:40:40.0869466+00:00"

如何从响应中提取变量“mainUrl”,以便将其值分配给 _pictureController?这是我所做的:

uploadFile() async 
  var accessToken = await sharedPref.read(key);
  var postUrl = '$baseUrl/catalogue?thumbnail=$param.thumbnailTrueFalse';
  Map < String, String > headers = 
    "Authorization": "Bearer $accessToken",
  ;

  // multipart request object
  var request = http.MultipartRequest("POST", Uri.parse(postUrl));
  request.headers.addAll(headers);

  // add selected file with request
  request.files.add(http.MultipartFile("file", imageStream, imageSize,
    filename: imageName));

  // Send request
  var response = await request.send();

  // Read response
  var result = await response.stream.bytesToString();
  print('readResponse: $result');
  if (response.statusCode == 200) 
    var data = StorageResponse.fromJson(jsonDecode(result));
    print('data: $data');
    setState(() 
      _pictureController.text = data.catalogueUrl!.mainUrl!;
    );
    return data;
   else 
    throw Exception('Failed to upload photo.');
  

“StorageResponse”类如下:

@JsonSerializable()
class StorageResponse 
  var id;
  var name;
  var fileKey;
  var fileExtension;
  var mimeType;
  Catalogue ? catalogueUrl;
  var createdAt;

  StorageResponse(
    this.id,
    this.name,
    this.fileKey,
    this.fileExtension,
    this.mimeType,
    this.catalogueUrl,
    this.createdAt,
  );

  factory StorageResponse.fromJson(Map < String, dynamic > json) =>
    _$StorageResponseFromJson(json);
  Map < String, dynamic > toJson() => _$StorageResponseToJson(this);

  @override
  toString() 
    String output =
      'id:$this.id,name:$this.name,fileKey: $this.fileKey,fileExtension:$this.fileExtension,mimeType: $this.mimeTypemimeType,catalogueUrl: $this.catalogueUrl,,createdAt: $this.createdAt';
    return output;
  

【问题讨论】:

【参考方案1】:

您可以使用以下结构将Json文件转换为类,反之亦然。

以下结构可以正常工作。

import 'dart:convert';

class StorageResponse 
  final String id;
  final String name;
  final String fileKey;
  final String fileExtension;
  final String mimeType;
  Catalogue catalogueUrl;
  final DateTime createdAt;

  StorageResponse(
    this.id,
    this.name,
    this.fileKey,
    this.fileExtension,
    this.mimeType,
    this.catalogueUrl,
    this.createdAt,
  );

  factory StorageResponse.fromMap(Map<String, dynamic> json) 
    return StorageResponse(
        json['id'],
        json['name'],
        json['fileKey'],
        json['fileExtension'],
        json['mimeType'],
        Catalogue.fromMap(json['Catalogue']),
        DateTime.parse(json['createdAt']));
  

  Map<String, dynamic> toJson() => 
        'id': id,
        'name': name,
        'fileKey': fileKey,
        'fileExtension': fileExtension,
        'mimeType': mimeType,
        'Catalogue': catalogueUrl.toJson(),
        'createdAt': createdAt
      ;

  @override
  toString() 
    String output =
        'id:$this.id,name:$this.name,fileKey: $this.fileKey,fileExtension:$this.fileExtension,mimeType: $this.mimeTypemimeType,catalogueUrl: $this.catalogueUrl,,createdAt: $this.createdAt';
    return output;
  


class Catalogue 
  final String mainUrl;
  final List<String> thumbnailUrls;

  Catalogue(this.mainUrl, this.thumbnailUrls);

  factory Catalogue.fromMap(Map<String, dynamic> json) 
    return Catalogue(json['mainUrl'], jsonDecode(json['thumbnailUrls']));
  

  Map<String, dynamic> toJson() =>
      'mainUrl': mainUrl, 'thumbnailUrls': jsonEncode(thumbnailUrls);

使用

if (response.statusCode == 200) 
     var data = StorageResponse.fromMap(jsonDecode(result));
    print('data: $data');
    setState(() 
      _pictureController.text = data.catalogueUrl!.mainUrl!;
    );
    return data;
   else 
    throw Exception('Failed to upload photo.');

【讨论】:

以上是关于如何从多部分/表单数据响应中提取数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 java 从多部分数据中读取正文内容?

如何从多类分类的混淆矩阵中提取假阳性、假阴性

Swift 2,如何从多阶段 JSON 响应中获取值

从多季度期间提取季度数据

GlobalMapper精品教程041:从多波段影像中提取单波段方法

GlobalMapper精品教程041:从多波段影像中提取单波段方法