sourcecode

Response JSON을 Flutter에서 객체로 변환하는 방법

copyscript 2023. 2. 15. 22:09
반응형

Response JSON을 Flutter에서 객체로 변환하는 방법

성공 JSON 문자열을 개체로 변환하려고 합니다.JSON을 오브젝트로 변환하는 것에 대해 몇 가지 질문이 있습니다.

또, 로그로 이 설명을 취득하고 있습니다.

NoSuchMethodError: Class '**_InternalLinkedHashMap<String, dynamic>' has no instance method 'cast' with matching arguments**.<br>
Receiver: _LinkedHashMap len:3
**Tried calling: cast<Map<String, dynamic>>()**
  1. 그 데이터 오브젝트도 모델에 캐스팅해야 하나요?
  2. 이것이 JSON을 오브젝트(SignUpResponse)로 변환하는 가장 간단하고 최선의 방법입니다.
  3. 시리얼라이제이션이 더 좋습니까?

응답 JSON:

{
    "data": {
        "_id": "5bd2a59f4c59de1ac517d7bf",
        "email": "fjhsd@gmail.com",
        "phoneNumber": "2417874147",
        "isAddressApproved": 0,
        "unitNumber": "144",
        "streetAddress": "sdfsddsf",
        "area": "asd",
        "zipCode": "112233",
        "totalOrder": 0,
        "todayOrder": 0,
        "isPauseDelivery": false,
        "vacationStartDt": null,
        "vacationEndDt": null,
        "defaultLiter": 1
    },
    "message": "New User Created",
    "error": false
}

온라인 도구로 작성된 SignUpResponse.

class SignUpResponse {
    Data data;
    String message;
    bool error;

    SignUpResponse({this.data, this.message, this.error});

    SignUpResponse.fromJson(Map<String, dynamic> json) {
    data = json['data'] != null ? new Data.fromJson(json['data']) : null;
    message = json['message'];
    error = json['error'];
    }

    Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    if (this.data != null) {
        data['data'] = this.data.toJson();
    }
    data['message'] = this.message;
    data['error'] = this.error;
    return data;
    }
}

class Data {
    String sId;
    String email;
    String phoneNumber;
    int isAddressApproved;
    String unitNumber;
    String streetAddress;
    String area;
    String zipCode;
    int totalOrder;
    int todayOrder;
    bool isPauseDelivery;
    Null vacationStartDt;
    Null vacationEndDt;
    int defaultLiter;

    Data(
        {this.sId,
        this.email,
        this.phoneNumber,
        this.isAddressApproved,
        this.unitNumber,
        this.streetAddress,
        this.area,
        this.zipCode,
        this.totalOrder,
        this.todayOrder,
        this.isPauseDelivery,
        this.vacationStartDt,
        this.vacationEndDt,
        this.defaultLiter});

    Data.fromJson(Map<String, dynamic> json) {
    sId = json['_id'];
    email = json['email'];
    phoneNumber = json['phoneNumber'];
    isAddressApproved = json['isAddressApproved'];
    unitNumber = json['unitNumber'];
    streetAddress = json['streetAddress'];
    area = json['area'];
    zipCode = json['zipCode'];
    totalOrder = json['totalOrder'];
    todayOrder = json['todayOrder'];
    isPauseDelivery = json['isPauseDelivery'];
    vacationStartDt = json['vacationStartDt'];
    vacationEndDt = json['vacationEndDt'];
    defaultLiter = json['defaultLiter'];
    }

    Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['_id'] = this.sId;
    data['email'] = this.email;
    data['phoneNumber'] = this.phoneNumber;
    data['isAddressApproved'] = this.isAddressApproved;
    data['unitNumber'] = this.unitNumber;
    data['streetAddress'] = this.streetAddress;
    data['area'] = this.area;
    data['zipCode'] = this.zipCode;
    data['totalOrder'] = this.totalOrder;
    data['todayOrder'] = this.todayOrder;
    data['isPauseDelivery'] = this.isPauseDelivery;
    data['vacationStartDt'] = this.vacationStartDt;
    data['vacationEndDt'] = this.vacationEndDt;
    data['defaultLiter'] = this.defaultLiter;
    return data;
    }
}

REST POST API 호출

void postCallSignUp(BuildContext context, var body) {
// This Function will check Internet is available or not.
Utils.checkConnection().then((connectionResult) {
    if (connectionResult) {
    http.post(Constants.BASE_URL + Constants.CREATE_USER,
        body: body,
        headers: {
            "Accept": "application/json",
            "content-type": "application/json"
        }).then((http.Response response) {
        final String res = response.body;
        final int statusCode = response.statusCode;

        if (statusCode < 200 || statusCode > 400 || json == null) {
        _onFailureResponse(new Exception("Error while fetching data"));
        } else {
        //Parsing json response to particular Object.
        print(json.decode(res));

        // Unable to cast json here...
        final parsed = json.decode(res).cast<Map<String, dynamic>>();
        parsed.map<SignUpResponse>((json) => SignUpResponse.fromJson(json));
        SignUpResponse signUpResponse = parsed.map<SignUpResponse>((json) => SignUpResponse.fromJson(json));
        _onSuccessResponse(signUpResponse);
        }
    });
    } else {
    _onNoInternetConnection();
    Utils.showAlert(context, "Alert", "Internet is not connected.", () {
        Navigator.pop(context);
    });
    }
});
}

여기서 무슨 일이 일어나고 있는지 이해할 수 없습니까?왜 우리는 우리의 아들을 특정 객체로 변환하기 위해 그렇게 많은 것을 해야 하는가?

캐스트를 사용할 필요가 없습니다. 지도에 직접 구문 분석할 수 있습니다.

final Map parsed = json.decode(res); 

지도를 작성한 후 해당 데이터를 사용하여 개체로 변환할 수 있습니다.

final signUp = SignUpResponse.fromJson(parsed);

오브젝트의 배열을 해석하는 경우는, 다음과 같은 조작을 실행할 수 있습니다.

//assuming this json returns an array of signupresponse objects
final List parsedList = json.decode(res); 

List<SignUpResponse> list = parsedList.map((val) =>  SignUpResponse.fromJson(val)).toList();

JSON:

    [
     {
       "id":1,
       "name":"Afghanistan",
       "iso3":"AFG",
       "iso2":"AF",
       "phone_code":"93",
       "capital":"Kabul",
       "currency":"AFN"
     },
     {
       "id":2,
       "name":"Aland Islands",
       "iso3":"ALA",
       "iso2":"AX",
       "phone_code":"+358-18",
       "capital":"Mariehamn",
       "currency":"EUR"
       },
    ]

POJO 클래스:

    class country{
       String id;
       String name;
       String currency;

       country({this.id,this.name,this.currency});

       factory country.fromJson(Map<String, dynamic> parsedJson){
         return country(
         id: parsedJson['id'].toString(),
         name : parsedJson['name'].toString(),
         currency: parsedJson['currency'].toString() 
         );
       }
    }

API 호출:

    await http.post("http://calikidsmap.com/test.php").then((response){

    var ddd=jsonDecode(response.body);

    Country_object_list = (ddd as List)
      .map((data) => new country.fromJson(data))
      .toList();

다음은 추가 절차 없이 요청 후 정보에 액세스하려는 경우의 기본 답변입니다.

 Map<String, dynamic> data = jsonDecode(response.body);
 String token = data["data"]["access_token"];

요청에서 객체의 구조는 다음과 같습니다.

{
  "success":1,
  "error":[],
  "data": {
     "access_token":"13d2ec9d1094903b1e81de8af059233e9f36ec4d",
     "expires_in":2628000,
     "token_type":"Bearer"
  }
}

같은 답변이지만 중첩된 JsonObjects가 있으면 어떻게 됩니까?간단:

다음과 같은 jsonResponse가 지정됩니다.

{
  "id": 1,
  "type": 15,
  "innerClass": {
    "id": 1,
    "type": "testing"
  }
}

다음은 코드의 예를 제시하겠습니다.

class MainClass {
  int id = 0;
  int version = 0;
  InnerClass innerClass;

  MainClass (
      this.id,
      this.version,
      this.innerClass
      );
  
//Create the same factory converter, but using another inner factory 'fromJson' converter
//for the inner class object (InnerClass.fromJson(json['inner_class']))

  factory MainClass.fromJson(dynamic json) {
    return MainClass(
        json['id'] as int, // << put your json response keys instead.
        json['version'] as int,
        InnerClass.fromJson(json['innerClass']) // << this one
    );
  }

그런 다음 내부 클래스 개체에 대해 동일한 전략을 반복합니다.

class InnerClass {
  int id = 0;
  String type = 'testing_type';
  InnerClass (
      this.id,
      this.type
      );
  factory InnerClass.fromJson(dynamic json) {
    return InnerClass(
        json['id'] as int,
        json['type'] as String
    );
  }
}

마지막으로, 프로젝트의 다른 부분에서 다음과 같이 설명할 수 있습니다.

try {
          mainClassDartObject = MainClass.fromJson(response.body);
     } catch (e) {
          print(e);
     }

이 항목을 에 추가합니다.pubspec.yaml

dependencies:
  # Your other regular dependencies here
  json_annotation: <latest_version>

dev_dependencies:
  # Your other dev_dependencies here
  build_runner: <latest_version>
  json_serializable: <latest_version>

오브젝트 클래스

import 'package:json_annotation/json_annotation.dart';


part 'user.g.dart'; //"user" is your dart file name

/// JSON serialization logic to be generated.
@JsonSerializable()

class User {
  User(this.name, this.email);

  String name;
  String email;

  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);

  Map<String, dynamic> toJson() => _$UserToJson(this);
}

Android Studio 터미널에서 실행하세요.

flutter pub run build_runner build

이제 다음과 같이 변환합니다.

Map results =  json.decode(response.body);
User user = User.fromJson(results);

출처: https://flutter.dev/docs/개발/data-and-backend/json

이 방법은 사용하기에 충분했습니다.http: ^0.13.3도서관

LoginResponseModel posts = LoginResponseModel();
    final response = await http.post(
      Uri.parse(URL HERE),
      headers: {
        "Content-Type": "application/x-www-form-urlencoded",
      },
      encoding: Encoding.getByName('utf-8'),
      body: {
        "param1": value1,
        "param2": value2,
        "param3": value3,
        "param4": value4
      },
    );

    if (response.statusCode == 200) {
      // If the server did return a 200 OK response,
      // then parse the JSON.
      final Map<String, dynamic> parsed = json.decode(response.body);
      posts = LoginResponseModel.fromJson(parsed);
    } else {
      // If the server did not return a 200 OK response,
      // then throw an exception.
    }

언급URL : https://stackoverflow.com/questions/53001839/how-to-convert-response-json-to-object-in-flutter

반응형