Flutter调用贷款模拟接口报FormatException: Unexpected end of input如何解决
错误根源
你错误地对字符串类型的response.body直接取下标[0],导致传给jsonDecode的内容只有单个字符[,完全不符合JSON格式,才触发了格式异常。你之前不加[0]报错是因为接口返回的是JSON数组,解码后是List类型,无法直接传给接收Map参数的fromJson方法,操作顺序完全搞反了。
修复方案
1. 修正LoanModel.simulators方法
因为你需要把数据渲染到ListView,接口本身也返回了多期还款数据,所以直接解析为List<LoanModel>返回即可:
static Future<List<LoanModel>> simulators({String periodtime, String interestpermonth, String loanamountrequest, String idUser, String url}) async { var url = "http://192.168.0.23/edufund-api/Api/loansimulation.php?periodtime=" + periodtime + "&interestpermonth=" + interestpermonth + "&loanamountrequest=" +loanamountrequest; final response = await http.get(url,headers:{"Content-Type":"application/json"}); // 先解码整个响应字符串得到数组 List<dynamic> jsonList = jsonDecode(response.body); // 遍历数组把每一项转成LoanModel对象 List<LoanModel> resList = jsonList.map((item) => LoanModel.fromJson(item)).toList(); print(response.body); return resList; }
2. 修正贷款模拟处理逻辑
适配返回的列表数据,同时增加异常捕获避免崩溃:
void result() async { try { List<LoanModel> loanList = await LoanModel.simulators( periodtime: periodtime, interestpermonth: interestpermonth, loanamountrequest: loanamountrequest, url: BaseURL.kLoanSimulationUrl2 ); // 取第一条的状态判断请求是否成功 if (loanList.isNotEmpty && loanList.first.status == true) { // 把列表传到Simulator页面用于渲染ListView Navigator.pushReplacementNamed(context, Simulator.id, arguments: loanList); } else { _scaffoldKey.currentState.showSnackBar(SnackBar( content: Text("获取贷款模拟数据失败"), duration: Duration(seconds: 3), )); } } catch(e) { _scaffoldKey.currentState.showSnackBar(SnackBar( content: Text("请求出错:${e.toString()}"), duration: Duration(seconds: 3), )); } }
3. Simulator页面渲染ListView示例
在Simulator页面接收传递的列表,直接构建列表即可:
class Simulator extends StatefulWidget { static const String id = "Simulator"; @override _SimulatorState createState() => _SimulatorState(); } class _SimulatorState extends State<Simulator> { @override Widget build(BuildContext context) { // 接收传入的还款计划列表 List<LoanModel> loanList = ModalRoute.of(context).settings.arguments as List<LoanModel>; return Scaffold( appBar: AppBar(title: Text("贷款模拟结果")), body: ListView.builder( itemCount: loanList.length, itemBuilder: (context, index) { final item = loanList[index]; return ListTile( title: Text("第${item.no}期"), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("月供:${item.installment}"), Text("利息:${item.interest},本金:${item.principal}"), Text("剩余本金:${item.balance}"), ], ), ); }, ), ); } }
注意事项
- 你的LoanModel中定义的
message字段,接口返回的JSON里没有对应值,需要后端在请求失败的场景下补充返回该字段才能正常使用 - Android高版本默认禁止HTTP请求,需要在安卓配置文件中添加HTTP允许规则,同时确保测试手机和服务端在同一个局域网,能正常访问192.168.0.23的接口
内容的提问来源于stack exchange,提问作者user15043474
相关产品推荐
相关产品推荐

