Flutter通过模型类解码SharedPreferences存储的JSON接口响应字符串
问题根因
你当前的Result.encode实现存在错误:代码中调用了result.toString(),自定义类默认的toString方法返回的是实例描述字符串(类似Instance of 'Result'),不是标准JSON结构,所以存入SharedPreferences的内容本身就不具备反序列化还原为模型的条件,需要先修正序列化逻辑,再实现解码逻辑。
第一步:修正序列化相关代码
首先给两个模型类补充toJson方法,同时调整encode实现:
import 'dart:convert'; class Result { Result({ required this.table, required this.data, }); String table; List<Data> data; factory Result.fromJson(Map<String, dynamic> json) => Result( table: json["table"], data: List<Data>.from(json["data"].map((x) => Data.fromJson(x))), ); // 新增toJson方法 Map<String, dynamic> toJson() => { "table": table, "data": List<dynamic>.from(data.map((x) => x.toJson())), }; // 针对Result数组的序列化方法 static String encode(List<Result> results) => json.encode( results.map((result) => result.toJson()).toList(), ); // 针对单个Result对象的序列化方法 static String encodeSingle(Result result) => json.encode(result.toJson()); } class Data { Data({ required this.subjectName, required this.year, required this.credits, required this.sOrder, required this.result, required this.onlineAssignmentResult, }); String subjectName; String year; String credits; String sOrder; String result; String onlineAssignmentResult; factory Data.fromJson(Map<String, dynamic> json) => Data( subjectName: json["subject_name"], year: json["year"], credits: json["credits"], sOrder: json["s_order"], result: json["result"], onlineAssignmentResult: json["online_assignment_result"], ); // 新增toJson方法 Map<String, dynamic> toJson() => { "subject_name": subjectName, "year": year, "credits": credits, "s_order": sOrder, "result": result, "online_assignment_result": onlineAssignmentResult, }; }
接着调整接口请求后的存储逻辑,先把原始响应转为模型再序列化:
if (response.statusCode == 200) { // 如果接口返回的是单个Result对象,用这个: Result result = Result.fromJson(response.data); var resultData = Result.encodeSingle(result); // 如果接口返回的是Result数组,用这段替换上面两行: // List<Result> result = (response.data as List).map((e) => Result.fromJson(e)).toList(); // var resultData = Result.encode(result); prefs.setString('results', resultData); }
第二步:实现正确的解码逻辑
根据你存储的是单个对象还是数组,对应实现解码:
// 存储单个Result对象时的解码方法 Future<Result?> getSingleResultData() async { SharedPreferences prefs = await SharedPreferences.getInstance(); String? resultData = prefs.getString('results'); if (resultData == null) return null; Map<String, dynamic> decodedJson = jsonDecode(resultData); Result result = Result.fromJson(decodedJson); // 可直接使用模型属性 print(result.table); print(result.data.first.subjectName); return result; } // 存储Result数组时的解码方法 Future<List<Result>?> getResultListData() async { SharedPreferences prefs = await SharedPreferences.getInstance(); String? resultData = prefs.getString('results'); if (resultData == null) return null; List<dynamic> decodedList = jsonDecode(resultData); List<Result> resultList = decodedList.map((e) => Result.fromJson(e)).toList(); return resultList; }
内容的提问来源于stack exchange,提问作者Hashan
相关产品推荐
相关产品推荐

