HTTP POST with Json on Body - Flutter/Dart HTTP POST with Json on Body - Flutter/Dart dart dart

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