在flutter中使用json_serializable对json对象进行反序列化

Posted

技术标签:

【中文标题】在flutter中使用json_serializable对json对象进行反序列化【英文标题】:Deserialization of json objects using json_serializable in flutter 【发布时间】:2018-12-02 05:59:51 【问题描述】:

我在 json 注释的帮助下使用 json_serializable 包生成了代码。我已经构建了另一个模型类,用于将 json 类的特定属性映射到模型类。但是,在反序列化对象时,出现以下错误 int 类型不是字符串的子类型 从上面的错误我假设反序列化不会产生一个列表而是一个映射。我将模型类转换为列表,但没有帮助。由于我是飞镖新手,因此我对这个主题的理解有限。

这里是代码。

import 'package:json_annotation/json_annotation.dart';

part 'json.g.dart';

@JsonSerializable()
class BaseClass extends Object with _$BaseClassSerializerMixin 
@JsonKey(name: "location")
final Location location;
@JsonKey(name: "current")
final Current current;


BaseClass(this.location, this.current);

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


@JsonSerializable()
class Location extends Object with _$LocationSerializerMixin 
final String name;
final String region;
final String country;
final double lon;
final double lat;
@JsonKey(name: "tz_id")
final String timezone;
@JsonKey(name: "localtime")
final String localtime;

Location(
 this.country,
 this.lat,
 this.localtime,
 this.lon,
 this.name,
 this.region,
 this.timezone,
 );

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


@JsonSerializable()
class Current extends Object with _$CurrentSerializerMixin 
@JsonKey(name: "wind_mph")
final double windmph;
@JsonKey(name: "wind_kph")
final double windkph;
@JsonKey(name: "wind_dir")
final String windDirection;
@JsonKey(name: "wind_degree")
final double winddegree;
final int cloud;
@JsonKey(name: "pressure_mb")
final double pressuremb;
@JsonKey(name: "pressure_in")
final double pressurein;
@JsonKey(name: "precip_mm")
final double precipmm;
@JsonKey(name: "precip_in")
final double precipin;
final int humidity;
@JsonKey(name: "feelslike_c")
final double centrigade;
@JsonKey(name: "feelslike_f")
final double faranheit;
@JsonKey(name: "temp_c")
final double tempc;
@JsonKey(name: "temp_f")
final double tempf;
@JsonKey(name: "vis_km")
final double visionKM;
@JsonKey(name: "vis_miles")
final double visionM;

final Condition condition;

Current(
this.centrigade,
this.cloud,
this.faranheit,
this.humidity,
this.pressuremb,
this.tempc,
this.precipmm,
this.precipin,
this.pressurein,
this.tempf,
this.winddegree,
this.windkph,
this.windmph,
this.windDirection,
this.condition,
this.visionKM,
this.visionM,
);

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


@JsonSerializable() 
class Condition extends Object with _$ConditionSerializerMixin 
final String text;
final String icon;
final String code;

Condition(this.text, this.code, this.icon);

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

天气模型

 WeatherModel.fromResponse(BaseClass base)
  : centrigade = base.current.centrigade,
    tempc = base.current.tempc,
    tempf = base.current.tempf,
    faranheit = base.current.faranheit,
    cloud = base.current.cloud,
    humidity = base.current.humidity,
    winddegree = base.current.winddegree,
    windkph = base.current.windkph,
    windmph = base.current.windmph,
    precipin = base.current.precipin,
    precipmm = base.current.precipmm,
    pressuremb = base.current.pressuremb,
    pressurein = base.current.precipin,
    description = base.current.condition.text,
    icon = base.current.condition.icon;

反序列化代码

Future<List<WeatherModel>> getWeatherData(String city) async 
Uri uri = new Uri.https(
  "api.apixu.com", "v1/forecast.json", "key": key, "q": city);
print(uri);
final response = await http.get(uri);
final responseJson = json.decode(response.body);
print(responseJson);
var data = BaseClass.fromJson(responseJson);
print(data);
return WeatherModel.fromResponse(data) as List; 
//Tried (BaseClass.fromResponse(responseJson) as List).map((i => 
WeatherModel.fromResponse(i)).toList();

【问题讨论】:

【参考方案1】:

我不能 100% 确定 - 您应该在问题中包含来自 API 的示例 JSON 响应 - 但我认为它在您的 Condition 对象中。你有

final String text;
final String icon;
final String code;

但我认为应该是

final int code;

您描述的错误基本上意味着您的代码正在尝试将值解码为字符串,但找到了int,因此无法对其进行解码。

此外,您可能希望将 wind_degree 从 Double 更改为 Int,至少根据 apixu 文档。

【讨论】:

是的。下次我会记住添加 Json 响应。错误是由于数据类型不匹配造成的。感谢您指出了这一点。我仍然不敢相信我错过了。 这可能发生在我们最好的人身上 =) 诀窍就是解释错误代码。

以上是关于在flutter中使用json_serializable对json对象进行反序列化的主要内容,如果未能解决你的问题,请参考以下文章

在 Flutter Web 中使用 Flutter 移动包

如何使用 flutter_webview 插件在 Flutter 中启用位置?

在flutter中使用Chopper网络库和flutter_bloc库

Flutter : 在 Flutter web 中使用 Froala-editor

如何在flutter中使用flutter_webview_plugin和AndroidX

在 Flutter 中使用 webview_flutter 4.0 | 基础用法与事件处理