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

Flutter从本地Flask服务获取JSON报Null转String类型不匹配错误

问题:Flutter解析本地Flask GPS数据时出现type 'Null' is not a subtype of type 'String'错误

错误现象

  • Flask后端(Python3.9+Flask)运行在localhost:5000,GPS数据JSON可正常访问并更新
  • Flutter应用请求数据后展示时抛出错误:type 'Null' is not a subtype of type 'String'

相关代码

Flutter数据获取与模型类

import 'dart:convert';

import 'package:http/http.dart' as http;

Future<Album> fetchAlbum() async {
  final response = await http.get(Uri.parse('http://127.0.0.1:5000/gps'));

  if (response.statusCode == 200) {
    return Album.fromJson(jsonDecode(response.body));
  } else {
    throw Exception('something messed up');
  }
}

class Album {
  final String lat;
  final String latD;
  final String long;
  final String longD;
  final String date;
  final String time;
  final String sv;

  const Album({
    required this.lat,
    required this.latD,
    required this.long,
    required this.longD,
    required this.date,
    required this.time,
    required this.sv,
  });

  factory Album.fromJson(Map<String, dynamic> json) {
    return Album(
      lat: json['lat'],
      latD: json['latD'],
      long: json['long'],
      longD: json['longD'],
      date: json['date'],
      time: json['time'],
      sv: json['sv'],
    );
  }
}

Flutter数据展示代码

class _GPSState extends State<GPS> {
  late Future<Album> futureAlbum;

  @override
  void initState() {
    super.initState();
    futureAlbum = fetchAlbum();
  }
body: Row(
        mainAxisSize: MainAxisSize.max,
        children: <Widget>[
          Expanded(
            flex: 1,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              mainAxisSize: MainAxisSize.max,
              children: [
                Expanded(
                  child: ListTile(
                    title: Text('GPS LAT'),
                    subtitle: FutureBuilder<Album>(
                      future: futureAlbum,
                      builder: (context, snapshot) {
                        if (snapshot.hasData) {
                          print(snapshot.data!.lat);
                          return Text(snapshot.data!.lat);
                        } else if (snapshot.hasError) {
                          return Text('${snapshot.error}');
                        }

                        // By default, show a loading spinner.
                        return const CircularProgressIndicator();
                      },
                    ),
                  ),
                ),

后端返回的JSON结构

{
"alt":"7.0",
"date":"2022-11-04",
"la_dir":"N",
"lat":"52.45063566666666",
"ln_dir":"W",
"long":"-117.36322",
"sv":"12",
"time":"22:32:47"
}

问题原因与解决方案

核心原因

Flutter的Album模型中定义了latD和longD字段,但后端返回的JSON里对应的键名是la_dir和ln_dir,导致解析时json['latD']和json['longD']返回Null,而Album类要求这两个字段是非空String,因此抛出类型不匹配错误。

修复方案

有两种可选方式:

  1. 修改Flutter模型类,与JSON键名对齐:
    修改Album类的字段名、构造函数和fromJson方法,同时添加空值兜底避免后续潜在崩溃:

    class Album {
      final String lat;
      final String laDir;
      final String long;
      final String lnDir;
      final String date;
      final String time;
      final String sv;
    
      const Album({
        required this.lat,
        required this.laDir,
        required this.long,
        required this.lnDir,
        required this.date,
        required this.time,
        required this.sv,
      });
    
      factory Album.fromJson(Map<String, dynamic> json) {
        return Album(
          lat: json['lat'] ?? '',
          laDir: json['la_dir'] ?? '',
          long: json['long'] ?? '',
          lnDir: json['ln_dir'] ?? '',
          date: json['date'] ?? '',
          time: json['time'] ?? '',
          sv: json['sv'] ?? '',
        );
      }
    }
    

    若展示代码中用到latD/longD,同步更新为laDir/lnDir。

  2. 修改Flask后端,将JSON返回的键名改为latD和longD,与Flutter模型对齐。

额外优化建议

  • Android模拟器访问本地Flask服务时,需把http://127.0.0.1:5000改为http://10.0.2.2:5000(模拟器将10.0.2.2映射到主机localhost)
  • 为Flask服务开启跨域支持(可使用flask-cors库),避免跨域请求被拦截

内容的提问来源于stack exchange,提问作者dunkaru

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 12:30:58