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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 14:36:06