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?
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 ;-)
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;
}
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}");
});
}
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.