Flutter调用FastAPI发送POST请求返回null,数据类型不匹配如何解决
问题描述
假设存在red、green、blue三个整数类型值,执行预测后会返回String类型的结果。当前遇到的问题是API无法读取Flutter中声明的String类型参数,且由于TextEditingController无法直接读取整数,在Flutter中识别、转换数据类型存在较大困难。
相关代码
main.dart
import 'package:flutter/material.dart'; import 'package:flutter_http_post/rgbModel.dart'; import 'package:http/http.dart' as http; void main() { runApp(MyApp()); } class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { RgbModel? _rgbcolor; final TextEditingController rController = TextEditingController(); final TextEditingController gController = TextEditingController(); final TextEditingController bController = TextEditingController(); Future<RgbModel> createRGB(String red, String green, String blue) async { final response = await http.post(Uri.parse('http://10.0.2.2:8000/predict/'), body: {"red": red, "green": green, "blue": blue}); if (response.statusCode == 200 || response.statusCode == 422) { final String responseBody = response.body; return rgbModelJson(responseBody); } else { throw Exception("Failed"); } } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: Container( padding: EdgeInsets.all(10), child: Column( children: [ TextField( controller: rController, decoration: InputDecoration(hintText: 'Enter Value R'), ), TextField( controller: gController, decoration: InputDecoration(hintText: 'Enter Value G'), ), TextField( controller: bController, decoration: InputDecoration(hintText: 'Enter Value G'), ), SizedBox( height: 10, ), _rgbcolor == null ? Container() : Text('The prediction ${_rgbcolor?.color}'), ElevatedButton( onPressed: () async { var rd = rController.text; var grn = gController.text; var bl = bController.text; final RgbModel? usercolor = await createRGB(rd, grn, bl); setState(() { _rgbcolor = usercolor; }); }, child: Text('Post')) ], ), ), ), ); } }
rgbModel.dart
import 'dart:convert'; RgbModel rgbModelJson(String str) => RgbModel.fromJson(json.decode(str)); String userModelToJson(RgbModel data) => json.encode(data.toJson()); class RgbModel { String? color; String? red; String? green; String? blue; RgbModel({ this.color, this.red, this.green, this.blue, }); factory RgbModel.fromJson(Map<String, dynamic> json) => RgbModel( color: json["color"], red: json["red"].toString(), green: json["green"].toString(), blue: json["blue"].toString(), ); Map<String, dynamic> toJson() => { "color": color, "red": red, "green": green, "blue": blue, }; }
VSCode的调试控制台未输出明确的代码错误结论。
问题现象
- Flutter端发起请求后返回null值
- 后端使用FastAPI,单独测试接口传入red、green、blue值可正常返回预期预测结果(例如"black")
解决方案
1. 修正请求格式与参数类型
问题核心是FastAPI要求接收int类型的rgb参数,且默认接收json格式的请求体,原代码传的是字符串类型的form格式参数,会触发FastAPI参数校验失败。
修改main.dart中的createRGB方法:
// 需先在main.dart顶部引入依赖 import 'dart:convert'; Future<RgbModel> createRGB(String red, String green, String blue) async { // 将输入的字符串转为int类型 final int redInt = int.parse(red); final int greenInt = int.parse(green); final int blueInt = int.parse(blue); final response = await http.post( Uri.parse('http://10.0.2.2:8000/predict/'), // 配置请求头说明是json格式 headers: {"Content-Type": "application/json"}, // 序列化请求体为json字符串,传入int类型参数 body: jsonEncode({"red": redInt, "green": greenInt, "blue": blueInt}), ); if (response.statusCode == 200) { final String responseBody = response.body; return rgbModelJson(responseBody); } else { // 打印错误信息方便排查 print("请求错误,状态码:${response.statusCode},返回内容:${response.body}"); throw Exception("请求失败,状态码: ${response.statusCode}"); } }
2. 优化输入框配置避免非法输入
给TextField增加数字输入限制,防止用户输入非数字内容导致类型转换失败,同时修正B输入框的hint文本错误:
// 需先在main.dart顶部引入依赖 import 'package:flutter/services.dart'; // R输入框示例,G、B输入框同理配置 TextField( controller: rController, decoration: const InputDecoration(hintText: 'Enter Value R'), keyboardType: TextInputType.number, inputFormatters: [FilteringTextInputFormatter.digitsOnly], ), TextField( controller: gController, decoration: const InputDecoration(hintText: 'Enter Value G'), keyboardType: TextInputType.number, inputFormatters: [FilteringTextInputFormatter.digitsOnly], ), TextField( controller: bController, decoration: const InputDecoration(hintText: 'Enter Value B'), // 修正原hint文本错误 keyboardType: TextInputType.number, inputFormatters: [FilteringTextInputFormatter.digitsOnly], ),
3. 可选:异常捕获优化
可以在点击按钮的逻辑里增加类型转换异常捕获,避免用户输入超出int范围的内容触发崩溃:
ElevatedButton( onPressed: () async { try { var rd = rController.text; var grn = gController.text; var bl = bController.text; if(rd.isEmpty || grn.isEmpty || bl.isEmpty) { // 可自行增加空值提示逻辑 return; } final RgbModel? usercolor = await createRGB(rd, grn, bl); setState(() { _rgbcolor = usercolor; }); } catch(e) { print("处理错误:$e"); } }, child: const Text('Post') )
内容的提问来源于stack exchange,提问作者0732sta
相关产品推荐
相关产品推荐

