带有 Json 的 HTTP POST 正文 - Flutter/Dart

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/50278258/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 19:07:21  来源:igfitidea点击:

HTTP POST with Json on Body - Flutter/Dart

jsonpostdartflutter

提问by Cláudio Almeida

This is my code to make a request to an API:

这是我向 API 发出请求的代码:

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;

Future<http.Response> postRequest () async {
  var url ='https://pae.ipportalegre.pt/testes2/wsjson/api/app/ws-authenticate';
  var body = jsonEncode({ 'data': { 'apikey': '12345678901234567890' } });

  print("Body: " + body);

  http.post(url,
      headers: {"Content-Type": "application/json"},
      body: body
  ).then((http.Response response) {
    print("Response status: ${response.statusCode}");
    print("Response body: ${response.contentLength}");
    print(response.headers);
    print(response.request);

  });
  }

I have a problem with the response from the request, where its suppose to have a body with json, but something went wrong and i think is with the json that i send on the body request, because it is a nested json object, and the value of the key is a json object. i would love to know how i can parse the json right and insert into body of the request.

我对请求的响应有问题,它假设有一个带有 json 的主体,但是出了点问题,我认为是我在主体请求中发送的 json,因为它是一个嵌套的 json 对象,并且键的值是一个 json 对象。我很想知道如何正确解析 json 并插入到请求正文中。

this is the header response:

这是标头响应:

 {set-cookie: JSESSIONID=DA65FBCBA2796D173F8C8D78AD87F9AD;path=/testes2/;HttpOnly, last-modified: Thu, 10 May 2018 17:15:13 GMT, cache-control: no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0, date: Thu, 10 May 2018 17:15:13 GMT, content-length: 0, pragma: no-cache, content-type: text/html, server: Apache-Coyote/1.1, expires: Tue, 03 Jul 2001 06:00:00 GMT}

and this is how is suppose to be:

这就是假设的方式:

Server: Apache-Coyote/1.1
Expires: Tue, 03 Jul 2001 06:00:00 GMT
Last-Modified: Thu, 10 May 2018 17:17:07 GMT
Cache-Control: no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0
Pragma: no-cache
Content-Type: application/json;charset=UTF-8
Vary: Accept-Encoding
Set-Cookie: JSESSIONID=84813CC68E0E8EA6021CB0B4C2F245BC;path=/testes2/;HttpOnly
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked

the body response came empty and i think its because the body i sent on the request, can anyone help me with the nested json object in value??

正文响应为空,我认为这是因为我在请求中发送了正文,有人可以帮助我处理嵌套的 json 对象吗?

SCREENSHOT OF POSTMAN:

邮递员截图:

回答by Raj Yadav

This works!

这有效!

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;

Future<http.Response> postRequest () async {
  var url ='https://pae.ipportalegre.pt/testes2/wsjson/api/app/ws-authenticate';

  Map data = {
    'apikey': '12345678901234567890'
  }
  //encode Map to JSON
  var body = json.encode(data);

  var response = await http.post(url,
      headers: {"Content-Type": "application/json"},
      body: body
  );
  print("${response.statusCode}");
  print("${response.body}");
  return response;
}

回答by Richard Heap

OK, finally we have an answer...

好吧,我们终于有了答案……

You are correctly specifying headers: {"Content-Type": "application/json"},to set your content type. Under the hood either the package httpor the lower level dart:io HttpClientis changing this to application/json; charset=utf-8. However, your server web application obviously isn't expecting the suffix.

您正确指定headers: {"Content-Type": "application/json"},设置您的内容类型。在引擎盖下,包http或较低级别dart:io HttpClient正在将其更改为application/json; charset=utf-8. 但是,您的服务器 Web 应用程序显然不需要后缀。

To prove this I tried it in Java, with the two versions

为了证明这一点,我在 Java 中尝试了两个版本

conn.setRequestProperty("content-type", "application/json; charset=utf-8"); // fails
conn.setRequestProperty("content-type", "application/json"); // works

Are you able to contact the web application owner to explain their bug? I can't see where Dart is adding the suffix, but I'll look later.

您能否联系 Web 应用程序所有者来解释他们的错误?我看不到 Dart 在哪里添加后缀,但我稍后会查看。

EDITLater investigation shows that it's the httppackage that, while doing a lot of the grunt work for you, is adding the suffix that your server dislikes. If you can't get them to fix the server then you can by-pass httpand use the dart:io HttpClientdirectly. You end up with a bit of boilerplate which is normally handled for you by http.

编辑后来的调查表明http,虽然为您做了很多繁重的工作,但它正在添加您的服务器不喜欢的后缀。如果您无法让他们修复服务器,那么您可以绕过httpdart:io HttpClient直接使用。您最终会得到一些通常由http.

Working example below:

下面的工作示例:

import 'dart:convert';
import 'dart:io';
import 'dart:async';

main() async {
  String url =
      'https://pae.ipportalegre.pt/testes2/wsjson/api/app/ws-authenticate';
  Map map = {
    'data': {'apikey': '12345678901234567890'},
  };

  print(await apiRequest(url, map));
}

Future<String> apiRequest(String url, Map jsonMap) async {
  HttpClient httpClient = new HttpClient();
  HttpClientRequest request = await httpClient.postUrl(Uri.parse(url));
  request.headers.set('content-type', 'application/json');
  request.add(utf8.encode(json.encode(jsonMap)));
  HttpClientResponse response = await request.close();
  // todo - you should check the response.statusCode
  String reply = await response.transform(utf8.decoder).join();
  httpClient.close();
  return reply;
}

Depending on your use case, it may be more efficient to re-use the HttpClient, rather than keep creating a new one for each request. Todo - add some error handling ;-)

根据您的用例,重用 HttpClient 可能更有效,而不是为每个请求不断创建一个新的。Todo - 添加一些错误处理 ;-)

回答by Keshav Aditya R.P

This would also work :

这也可以:

import 'package:http/http.dart' as http;

  sendRequest() async {

    Map data = {
       'apikey': '12345678901234567890'
    };

    var url = 'https://pae.ipportalegre.pt/testes2/wsjson/api/app/ws-authenticate';
    http.post(url, body: data)
        .then((response) {
      print("Response status: ${response.statusCode}");
      print("Response body: ${response.body}");
    });  
  }

回答by H?ng Tr?nh

I think many people have problems with Post 'Content-type': 'application / json'The problem here is parse data Map <String, dynamic>to json:

我想很多人都对 Post'Content-type': 'application / json'有问题这里的问题是将数据解析Map <String, dynamic>json

Hope the code below can help someone

希望下面的代码可以帮助某人

Model:

模型:

class ConversationReq {
  String name = '';
  String description = '';
  String privacy = '';
  String type = '';
  String status = '';

  String role;
  List<String> members;
  String conversationType = '';

  ConversationReq({this.type, this.name, this.status, this.description, this.privacy, this.conversationType, this.role, this.members});

  Map<String, dynamic> toJson() {

    final Map<String, dynamic> data = new Map<String, dynamic>();

    data['name'] = this.name;
    data['description'] = this.description;
    data['privacy'] = this.privacy;
    data['type'] = this.type;

    data['conversations'] = [
      {
        "members": members,
        "conversationType": conversationType,
      }
    ];

    return data;
  }
}

Request:

要求:

createNewConversation(ConversationReq param) async {
    HeaderRequestAuth headerAuth = await getAuthHeader();
    var headerRequest = headerAuth.toJson();
/*
{
            'Content-type': 'application/json',
            'x-credential-session-token': xSectionToken,
            'x-user-org-uuid': xOrg,
          }
*/

    var bodyValue = param.toJson();

    var bodydata = json.encode(bodyValue);// important
    print(bodydata);

    final response = await http.post(env.BASE_API_URL + "xxx", headers: headerRequest, body: bodydata);

    print(json.decode(response.body));
    if (response.statusCode == 200) {
      // TODO
    } else {
      // If that response was not OK, throw an error.
      throw Exception('Failed to load ConversationRepo');
    }
  }

回答by Hari Prasath

This one is for using HTTPClient class

这是用于使用 HTTPClient 类

 request.headers.add("body", json.encode(map));

I attached the encoded json body data to the header and added to it. It works for me.

我将编码的 json 正文数据附加到标题并添加到其中。这个对我有用。