HTTP POST с Json on Body - Flutter/Dart
Это мой код для запроса 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);
});
}
У меня проблема с ответом на запрос, в котором предполагается, что тело имеет json, но что-то пошло не так, и я думаю, что с json, который я отправляю по запросу body, потому что это вложенный объект json, и значение ключа является объектом json. Я хотел бы знать, как я могу разобрать JSON правильно и вставить в тело запроса.
это заголовок ответа:
{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}
и вот как это должно быть:
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
ответ body пуст, и я думаю, что это потому, что тело, которое я отправил по запросу, может ли кто-нибудь помочь мне с вложенным объектом json в значении??
СКРИНШОТ ПОЧТЫ:
Ответы
Ответ 1
ОК, наконец, у нас есть ответ...
Вы правильно указываете headers: {"Content-Type": "application/json"},
чтобы установить тип содержимого. Под капотом либо пакет http
либо нижний уровень dart:io HttpClient
меняет это на application/json; charset=utf-8
application/json; charset=utf-8
. Тем не менее, ваше веб-приложение на сервере, очевидно, не ожидает суффикса.
Чтобы доказать это, я попробовал это на Java, с двумя версиями
conn.setRequestProperty("content-type", "application/json; charset=utf-8"); // fails
conn.setRequestProperty("content-type", "application/json"); // works
Можете ли вы связаться с владельцем веб-приложения, чтобы объяснить их ошибку? Я не вижу, где Дарт добавляет суффикс, но я посмотрю позже.
EDIT. Позже исследование показывает, что это пакет http
, который, выполняя много усилий для вас, добавляет суффикс, который не нравится вашему серверу. Если вы не можете заставить их исправить сервер, вы можете обойти http
и напрямую использовать dart:io HttpClient
. В итоге вы получаете немного шаблона, который обычно обрабатывается для вас по http
.
Ниже приведен рабочий пример:
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;
}
В зависимости от вашего варианта использования может быть более эффективным повторное использование HttpClient, вместо того, чтобы создавать новый для каждого запроса. Todo - добавьте обработку ошибок ;-)
Ответ 2
Это работает!
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;
}
Ответ 3
Это также будет работать:
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}");
});
}
Ответ 4
Этот для использования класса HTTPClient
request.headers.add("body", json.encode(map));
Я прикрепил закодированные данные тела json к заголовку и добавил к нему. Меня устраивает.