Dart http package的post
方法仅接受String
,List<int>
或Map<String, String>
作为请求 body 。
我需要使用Content-Type标头application / json将此类的对象发送为主体:
class CreateListingRequest {
String title;
List<ListingImage> images;
List<int> categoryIds;
}
ListingImage
在哪里
class ListingImage {
String url;
int position;
}
在邮递员中,我将使用Content-Type标头application/json
将正文构建为原始json,
{
"title": "Testing transaction force fail",
"listing_images": [
{
"url": "https://picsum.photos/500/500/?image=336",
"position": 0
},
{
"url": "https://picsum.photos/500/500/?image=68",
"position": 1
},
{
"url": "https://picsum.photos/500/500/?image=175",
"position": 2
}
],
"category_ids": [19, 26]
}
在我看来,如果我可以发送Map<String, dynamic>
来解决问题,但我只能发送Map<String, String>
。
请帮助。
答案 0 :(得分:2)
使用String encoded = json.encode(theMap);
,然后发布encoded
。如果您需要特定的字符编码(例如utf-8),请进一步使用utf8.encode(encoded)
对字符串进行编码,然后发布结果字节数组。 (对于utf-8,第二步应该是不必要的,因为我认为这是默认设置。)
值得考虑这三种变体的作用:
List<int>
-发送不透明的字节数组String
对
使用字符编码将字符串转换成字节-并发送字节
数组Map<String, String>
-将字符串键/值对编码为x-www-form-urlencoded
并发送。如果要发送更复杂的数据,则需要将其转换为上述之一(并且服务器需要知道如何对其进行解码)。这就是content-type
标头有用的地方。最终,服务器接收一个字节数组,并将其转换回例如字符串,某些json,一组表单字段或图像。它知道如何根据标头和任何指定的编码来执行此操作。
答案 1 :(得分:1)
我在搜索如何使用List<Map<String, dynamic>>
发送POST请求时发现了这个问题
经过一番思考,我编写了代码来做到这一点。它也适用于最初的问题(您只需将函数的参数设置为Map<String, dynamic>
类型)。
import 'package:http/http.dart' as http;
import 'dart:convert';
//...
static const Map<String, String> _JSON_HEADERS = {
"content-type": "application/json"
};
void sendPost(List<Map<String, dynamic>> data) {
http.Client client = new http.Client();
final String encodedData = json.encode(data);
client.post(ADDRESS, //your address here
body: encodedData, headers: _JSON_HEADERS);
}
答案 2 :(得分:0)
有一个dart程序包,它为http请求提供了一些帮助程序类,以及一个有助于json序列化的程序包。
BasicUtils:https://github.com/Ephenodrom/Dart-Basic-Utils
JsonSerializable:https://flutter.dev/docs/development/data-and-backend/json
通过以下方式安装:
dependencies:
basic_utils: ^1.4.0
json_annotation: ^2.0.0
dev_dependencies:
test: '>=0.12.42 <2.0.0'
build_runner: ^1.0.0
json_serializable: ^2.0.0
用法
像这样更新您的课程:
import 'package:json_annotation/json_annotation.dart';
part 'CreateListingRequest.g.dart';
@JsonSerializable()
class CreateListingRequest {
String title;
List<ListingImage> images;
List<int> categoryIds;
factory CreateListingRequest.fromJson(Map<String, dynamic> json) =>
_$CreateListingRequestFromJson(json);
Map<String, dynamic> toJson() => _$CreateListingRequestToJson(this);
}
import 'package:json_annotation/json_annotation.dart';
part 'ListingImage.g.dart';
@JsonSerializable()
class ListingImage {
String url;
int position;
factory ListingImage.fromJson(Map<String, dynamic> json) =>
_$ListingImageFromJson(json);
Map<String, dynamic> toJson() => _$ListingImageToJson(this);
}
使用以下命令创建* .g.dart文件:
pub run build_runner build
现在您的工作区中有一些* .g.dart文件。之后,您可以将您的类用于您的http请求。
//Convert class to string
String body = json.encode(payload.toJson());
// Convert response to class
MyResponseClass responseAsClass = MyResponseClass.fromJson(responseData);
完整示例
// Define some headers and query parameters
Map<String, String> headers = {
"Accept": "application/json"
};
Map<String, String> queryParameters = {
"foo": "bar"
};
// Create instance of the class
CreateListingRequest payload = CreateListingRequest();
// Convert class to String
String body = json.encode(payload.toJson()); // that does the magic :)
// Send request
Map<String, dynamic> responseData = await HttpUtils.postForJson("api.com/dosomething", body,
headers: headers, queryParameters: queryParameters);
// Convert response to class
MyResponseClass responseAsClass = MyResponseClass.fromJson(responseData);
其他信息:
这些都是HttpUtils类中的所有方法。
Future<Map<Response> getForFullResponse(String url,{Map<String, dynamic> queryParameters,Map<String, String> headers});
Future<Map<String, dynamic>> getForJson(String url,{Map<String, dynamic> queryParameters,Map<String, String> headers});
Future<String> getForString(String url,{Map<String, dynamic> queryParameters,Map<String, String> headers});
Future<Map<Response> postForFullResponse(String url, String body,{Map<String, String> queryParameters,Map<String, String> headers});
Future<Map<String, dynamic>> postForJson(String url, String body,{Map<String, String> queryParameters,Map<String, String> headers});
Future<String> postForString(String url, String body,{Map<String, String> queryParameters,Map<String, String> headers});
Future<Response> putForFullResponse(String url, String body,{Map<String, String> queryParameters,Map<String, String> headers});
Future<Map<String, dynamic>> putForJson(String url, String body,{Map<String, String> queryParameters,Map<String, String> headers});
Future<String> putForString(String url, String body,{Map<String, String> queryParameters,Map<String, String> headers});
Future<Response deleteForFullResponse(String url,{Map<String, String> queryParameters,Map<String, String> headers});
Future<Map<String, dynamic>> deleteForJson(String url,{Map<String, String> queryParameters,Map<String, String> headers});
Future<String> deleteForString(String url,{Map<String, String> queryParameters,Map<String, String> headers});
Map<String, dynamic> getQueryParameterFromUrl(String url);
String addQueryParameterToUrl(String url, Map<String, dynamic> queryParameters);
答案 3 :(得分:0)
如果您需要将复杂的数据作为 POST
请求的正文发布,即,将其作为对象本身发布,而不是作为服务器最终必须再次解码的 JSON 编码字符串发布,您可以使用 Flutter 包 Dio
而不是 http
。我刚刚发布了这个:
import 'package:dio/dio.dart';
Response res;
Dio dio = new Dio();
try {
res = await dio.post('<url>', data: {
"Body": {
"stkCallback": {
"MerchantRequestID": "21605-295434-4",
"CheckoutRequestID": "ws_CO_04112017184930742",
"ResultCode": '0',
"ResultDesc": "The service request is processed successfully.",
"CallbackMetadata": {
"Item": [
{"Name": "Amount", "Value": 1},
{"Name": "MpesaReceiptNumber", "Value": "LK451H35OP"},
{"Name": "Balance"},
{"Name": "TransactionDate", "Value": 20171104184944},
{"Name": "PhoneNumber", "Value": 254727894083}
]
}
}
}
});
} catch (e) {
print('Caught an error in API call!');
print('e is: ${e.toString()}');
Alert(context: context, title: 'Http POST error', desc: '$e').show();
if (res != null) print('Status code in apiCall() catch is ${res.statusCode}');
}
这是 Dio 包:https://pub.dev/packages/dio
答案 4 :(得分:0)
就我而言,我收到了 400 错误。我有这种类型的帖子正文
Map<String, dynamic> requestBodyMap = {"user":{"email":"test@test.com","password":"123456"}};
我使用
对其进行了编码String requestBody = json.encode(requestBodyMap);
并在 post 请求中发送了这个 body。问题是由于标题中的内容类型,它在标题中采用 application/x-www-form-urlencoded
类型。我将其更改为键入 application/json
,然后响应成功。
接受参数也有application/json
。