json - 如何在flutter中解析复杂的json数据并分配给模型?
问题描述
这是我用来从 api 获取数据然后将它们分配给模型的方法。
var headers = {
'API-Key': 'TEST_f+y9/tHG+yVxEq3uS3H1ogfezHSCWSq5MsIXUOnIV+Q',
'Content-Type': 'application/json',
};
var data = '"shipment": {
"validate_address": "no_validation",
"ship_to": {
"name": "Amanda Miller",
"phone": "555-555-5555",
"address_line1": "525 S Winchester Blvd",
"city_locality": "San Jose",
"state_province": "CA",
"postal_code": "95128",
"country_code": "US",
"address_residential_indicator": "yes"
},
"ship_from": {
"company_name": "Example Corp.",
"name": "John Doe",
"phone": "111-111-1111",
"address_line1": "4009 Marathon Blvd",
"address_line2": "Suite 300",
"city_locality": "Austin",
"state_province": "TX",
"postal_code": "78756",
"country_code": "US",
"address_residential_indicator": "no"
},
"packages": [
{
"weight": {
"value": 1.0,
"unit": "ounce"
}
}
]
}
}';
final response = await http.post('https://api.shipengine.com/v1/rates', headers: headers, body: data);
if (response.statusCode == 200) {
String responseBody = response.body;
var data = json.decode(responseBody);
print(data);
print(data["rate_response"]["rates"]);
ResRate rates = new ResRate.fromJson(data);
print(rates.rates[0].amount);
} else {
print(response.statusCode);
print(response.body);
}
}
是model.dart
// Amount amount;
List<Rates> rates;
ResRate({
// this.amount,
this.rates});
factory ResRate.fromJson(Map<String, dynamic> parsedJson){
var list = parsedJson['rates'] as List;
List<Rates> rates = list.map((i) => Rates.fromJson(i)).toList();
return ResRate(
// amount: Amount.fromJson(parsedJson['amount']),
rates: rates
);
}
}
class Amount{
var currency;
String amount;
Amount({this.currency,
this.amount});
factory Amount.fromJson(Map<String, dynamic> parsedJson){
return Amount(
currency: parsedJson['currency'],
amount : parsedJson['amount'],
);
}
}
class Rates{
var rate_id;
var rate_type;
var carrier_id;
Amount amount;
//List<Amount> shipping_amount;
Rates({
this.rate_id, this.amount,
this.rate_type, this.carrier_id,
});
factory Rates.fromJson(Map<String, dynamic> parsedJson){
// var list = parsedJson['images'] as List;
// List<Image> images = list.map((i) => Image.fromJson(i)).toList();
return Rates(
rate_id: parsedJson['rate_id'],
rate_type: parsedJson['rate_type'],
carrier_id: parsedJson['carrier_id'],
amount: Amount.fromJson(parsedJson['shipping_amount']),
);
}
}
但是我在控制台中遇到了这样的错误。
未处理的异常:NoSuchMethodError:在 null 上调用了方法“map”,它指向下面的模型代码
var list = parsedJson['rates'] as List;
List<Rates> rates = list.map((i) => Rates.fromJson(i)).toList();
我尝试打印响应正文,成功获取响应正文并在控制台中打印。对象速率也在响应中获取。但显示为空。由于此响应是一个复杂的响应,因此费率也有对象。这是从 api 获取的响应。
"rate_response": {
"rate_request_id": 501834,
"shipment_id": "se-2127183",
"status": "completed",
"created_at": "2019-07-26T22:10:50.286Z",
"rates": [
{
"rate_id": "se-11744390",
"rate_type": "shipment",
"carrier_id": "se-123890",
"shipping_amount": {
"currency": "usd",
"amount": 9.37
},
"insurance_amount": {
"currency": "usd",
"amount": 0.00
},
"confirmation_amount": {
"currency": "usd",
"amount": 0.00
},
"other_amount": {
"currency": "usd",
"amount": 0.00
},
"delivery_days": 3,
"guaranteed_service": false,
"estimated_delivery_date": "2019-07-26T05:00:00.000Z",
"carrier_delivery_days": "Friday by 11:00 PM",
"ship_date": "2019-07-26T05:00:00.000Z",
"negotiated_rate": false,
"service_type": "UPS® Ground",
"service_code": "ups_ground",
"trackable": true,
"validation_status": "valid",
"warning_messages": [],
"error_messages": [],
"carrier_code": "ups",
"carrier_nickname": "UPS-28A1R9",
"carrier_friendly_name": "UPS"
}
],
"invalid_rates": []
},
"shipment_id": "se-2127183",
"carrier_id": "",
"external_shipment_id": null,
"ship_date": "2019-07-26T05:00:00.000Z",
"created_at": "2019-07-26T22:10:50.286Z",
"modified_at": "2019-07-26T22:10:50.286Z",
"shipment_status": "pending",
"ship_to": {
"name": "Amanda Miller",
"phone": "555-555-5555",
"address_line1": "525 S Winchester Blvd",
"city_locality": "San Jose",
"state_province": "CA",
"postal_code": "95128",
"country_code": "US",
"address_residential_indicator": "yes"
},
"ship_from": {
"company_name": "Example Corp.",
"name": "John Doe",
"phone": "111-111-1111",
"address_line1": "4009 Marathon Blvd",
"address_line2": "Suite 300",
"city_locality": "Austin",
"state_province": "TX",
"postal_code": "78756",
"country_code": "US",
"address_residential_indicator": "no"
},
"return_to": {
"company_name": "Example Corp.",
"name": "John Doe",
"phone": "111-111-1111",
"address_line1": "4009 Marathon Blvd",
"address_line2": "Suite 300",
"city_locality": "Austin",
"state_province": "TX",
"postal_code": "78756",
"country_code": "US",
"address_residential_indicator": "no"
},
"confirmation": "none",
"advanced_options": {
"bill_to_account": null,
"bill_to_country_code": null,
"bill_to_party": null,
"bill_to_postal_code": null,
"contains_alcohol": false,
"custom_field1": null,
"custom_field2": null,
"custom_field3": null,
"non_machinable": false,
"saturday_delivery": false
},
"insurance_provider": "none",
"tags": [],
"total_weight": {
"value": 1.00,
"unit": "ounce"
},
"packages": [
{
"weight": {
"value": 1.00,
"unit": "ounce"
},
"dimensions": {
"unit": "inch",
"length": 0.0,
"width": 0.0,
"height": 0.0
},
"insured_value": {
"currency": "usd",
"amount": 0.0
}
}
]
}
解决方案
我自己找到了一个修复方法,结果我需要在模型中映射时从数组中添加子列表和对象头。
\\replace this
var list = parsedJson['rates'] as List;
\\with this
var list = parsedJson["rate_response"]['rates'] as List;
List<Rates> rates = list.map((i) => Rates.fromJson(i)).toList();