HTTP POST with Json on Body - Flutter/Dart
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;}
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 http
or the lower level dart:io HttpClient
is changing this to application/json; charset=utf-8
. However, your server web application obviously isn't expecting the suffix.
To prove this I tried it in Java, with the two versions
conn.setRequestProperty("content-type", "application/json; charset=utf-8"); // failsconn.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.
EDITLater investigation shows that it's the http
package 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 http
and use the dart:io HttpClient
directly. You end up with a bit of boilerplate which is normally handled for you by 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 ;-)
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}"); }); }