web-dev-qa-db-fra.com

HTTP POST avec Json sur le corps - Flutter / Dart

Ceci est mon code pour faire une demande à une 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);

  });
  }

J'ai un problème avec la réponse de la demande, où il est supposé avoir un corps avec json, mais quelque chose s'est mal passé et je pense que c'est avec le json que j'envoie sur la demande de corps, parce que c'est un objet json imbriqué, et La valeur de la clé est un objet JSON. j'aimerais savoir comment je peux analyser le json droit et l'insérer dans le corps de la demande.

c'est la réponse en-tête:

 {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}

et voici comment est supposé être:

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

la réponse du corps est venue vide et je pense que c'est parce que le corps que j'ai envoyé à la demande, quelqu'un peut-il m'aider avec l'objet JSON imbriqué en valeur?

ÉCRAN DE POSTMAN:

21
Cláudio Almeida

OK, enfin nous avons une réponse ...

Vous spécifiez correctement headers: {"Content-Type": "application/json"}, pour définir votre type de contenu. Sous le capot, le package http ou le niveau inférieur Dart:io HttpClient le remplace par application/json; charset=utf-8. Cependant, votre application Web serveur n'attend évidemment pas le suffixe.

Pour le prouver, je l’ai essayé en Java, avec les deux versions

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

Pouvez-vous contacter le propriétaire de l'application Web pour expliquer son bogue? Je ne vois pas où Dart ajoute le suffixe, mais je regarderai plus tard.

EDIT Une enquête ultérieure montre que c'est le package http qui, tout en effectuant une grande partie du travail fastidieux pour vous, ajoute le suffixe que votre serveur n'aime pas. Si vous ne pouvez pas leur demander de réparer le serveur, vous pouvez contourner http et utiliser le Dart:io HttpClient directement. Vous vous retrouvez avec un peu de passe-partout qui est normalement traité pour vous par http.

Exemple de travail ci-dessous:

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;
}

Selon votre cas d'utilisation, il peut s'avérer plus efficace de réutiliser HttpClient plutôt que de continuer à en créer un pour chaque demande. Todo - ajoute un peu de gestion des erreurs ;-)

20
Richard Heap

Cela marche!

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;
}
27
Raj Yadav

Cela fonctionnerait aussi:

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}");
    });  
  }
7
Keshav Aditya R.P

Celui-ci est pour utiliser la classe HTTPClient

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

J'ai attaché les données du corps JSON codées à l'en-tête et y ai ajouté. Ça marche pour moi.

0
Hari Prasath