1. ホーム
  2. json

HTTP POST with Json on Body - Flutter/Dart

2023-09-25 08:25:02

質問

これは、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オブジェクトであり、キーの値は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

ボディレスポンスが空になったので、私がリクエストで送ったボディが原因だと思うのですが、誰か値のネストされたjsonオブジェクトで私を助けることができますか?

postmanのスクリーンショットです。

どのように解決するのですか?

OK、ついに答えが出ましたね...

正しく指定されているのは headers: {"Content-Type": "application/json"}, を指定しています。ボンネットの中では、パッケージの http または下位レベルの dart:io HttpClient に変えているのは application/json; charset=utf-8 . しかし、サーバーのウェブアプリケーションは明らかにこのサフィックスを期待していません。

これを証明するために、私は2つのバージョンで、Javaでそれを試してみました。

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

Webアプリケーションの所有者に連絡して、そのバグを説明することができますか?Dartがどこにサフィックスを追加しているのかがわからないのですが、後で見てみます。

EDIT 後の調査で、それは http パッケージが、あなたのために多くの grunt 作業を行いながら、あなたのサーバが嫌うサフィックスを追加していることがわかりました。もし、サーバーを修正させることができないのであれば、 バイパスで 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 - いくつかのエラー処理を追加してください ;-)