You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 14:24:03