programing

본체에 Json이 있는 HTTP POST - 플래터/다트

itsource 2023. 3. 8. 23:02
반응형

본체에 Json이 있는 HTTP POST - 플래터/다트

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 오브젝트이기 때문입니다.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 response가 비어있어서 요청으로 보낸 body 때문인 것 같은데, nested json object 값에서 누가 도와줄 수 있나요?

우체부 스크린샷:

이거 돼!

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

그래, 드디어 답이 나왔군...

올바르게 지정하고 있습니다.headers: {"Content-Type": "application/json"},콘텐츠 유형을 설정합니다.후드 아래 또는 패키지 아래http또는 하위 레벨dart:io HttpClient이것을 로 바꾸고 있다.application/json; charset=utf-8다만, 서버 Web 애플리케이션은, 서픽스를 상정하고 있지 않은 것이 분명합니다.

이를 증명하기 위해 자바에서 두 가지 버전으로 시도했습니다.

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

웹 애플리케이션 소유자에게 연락하여 버그를 설명할 수 있습니까?다트가 어디에 접미사를 붙이는지는 모르겠지만 나중에 볼게요.

편집 나중의 조사에서는, 그 이유는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를 계속 새로 만드는 것보다 HttpClient를 다시 사용하는 것이 더 효율적일 수 있습니다.작업 - 오류 처리 추가;-)

이것도 동작합니다.

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

나는 많은 사람들이 포스트에 문제가 있다고 생각한다.'Content-type': 'application / json'여기서의 문제는 데이터를 해석하는 것입니다.Map <String, dynamic>로.json:

아래 코드가 도움이 되기를 바랍니다.

모델:

class ConversationReq {
  String name = '';
  String description = '';
  String privacy = '';
  String type = '';
  String status = '';

  String role;
  List<String> members;
  String conversationType = '';

  ConversationReq({this.type, this.name, this.status, this.description, this.privacy, this.conversationType, this.role, this.members});

  Map<String, dynamic> toJson() {

    final Map<String, dynamic> data = new Map<String, dynamic>();

    data['name'] = this.name;
    data['description'] = this.description;
    data['privacy'] = this.privacy;
    data['type'] = this.type;

    data['conversations'] = [
      {
        "members": members,
        "conversationType": conversationType,
      }
    ];

    return data;
  }
}

요청:

createNewConversation(ConversationReq param) async {
    HeaderRequestAuth headerAuth = await getAuthHeader();
    var headerRequest = headerAuth.toJson();
/*
{
            'Content-type': 'application/json',
            'x-credential-session-token': xSectionToken,
            'x-user-org-uuid': xOrg,
          }
*/

    var bodyValue = param.toJson();

    var bodydata = json.encode(bodyValue);// important
    print(bodydata);

    final response = await http.post(env.BASE_API_URL + "xxx", headers: headerRequest, body: bodydata);

    print(json.decode(response.body));
    if (response.statusCode == 200) {
      // TODO
    } else {
      // If that response was not OK, throw an error.
      throw Exception('Failed to load ConversationRepo');
    }
  }

이거면 돼

String body = json.encode(parameters);

http.Response response = await http.post(
  url: 'https://example.com',
  headers: {"Content-Type": "application/json"},
  body: body,
);

다음과 같이 구현합니다.

static createUserWithEmail(String username, String email, String password) async{
    var url = 'http://www.yourbackend.com/'+ "users";
    var body = {
        'user' : {
          'username': username,
          'address': email,
          'password': password
       }
    };

    return http.post(
      url, 
      body: json.encode(body),
      headers: {
        "Content-Type": "application/json"
      },
      encoding: Encoding.getByName("utf-8")
    );
  }

이것은 HTTP Client 클래스를 사용하기 위한 것입니다.

 request.headers.add("body", json.encode(map));

부호화된 json body 데이터를 헤더에 첨부하여 추가하였습니다.저는 좋아요.

제 경우 Flutter App의 POST는 웹에서 작동하지만 Android 기기나 에뮬레이터에서는 작동하지 않습니다.

플래터 -> 서버 ->API

이 문제를 해결하기 위해:

  1. 서버의 HTTP 헤더가 다음과 같이 변경되었습니다.

    $curlArr[CURLOPT_HTTPHEADER] = str_replace("application/x-www-form-urlencoded; charset=utf-8",
      "application/x-www-form-urlencoded",$curlArr[CURLOPT_HTTPHEADER]);
    
  2. 대부분의 헤더를 우체부에서 앱으로 복사했습니다.

String body = json.encode(parameters);

http.Response response = await http.post(
  url: Uri.parse('https://example.com'),
  headers: {"Content-Type": "application/json"},
  body: body,
);

나한텐 효과가 있었어!

이 코드는 유효합니다.

static Future<LoginAPI> connectToAPI(String email, String password) async {
    String apiURL = "domain/login";

    Map<String, String> headers = {
      "Content-Type": "application/json",
      "Accept": "application/json",
    };

    var body = json.encode({"email": email, "password": password});

    var apiResult = await http.post(
      Uri.parse(apiURL),
      headers: headers,
      body: body,
    );

    var jsonObject = json.decode(apiResult.body);
    if (apiResult.statusCode >= 300) {
      return jsonObject // you can mapping json object also here
    } else {
      return jsonObject // you can mapping json object also here
    }
  }

freeze를 사용하는 경우 먼저 인코딩하는 것을 잊지 마십시오.아마 잊기 쉬울 거야

String body = json.encode(parameters.toJson()); //dont skip this one
http.Response response = await http.post(
  Uri.parse(apiURL),
  headers: {"Content-Type": "application/json"},
  body: body,
);

제 경우, 이 기능을 활성화하는 것을 잊었다.

app.use(express.json());

내 NodeJs 서버에 있습니다.

언급URL : https://stackoverflow.com/questions/50278258/http-post-with-json-on-body-flutter-dart

반응형