Flutter嵌套JSON解析求助:值为字符串列表的键值对处理
Flutter解析嵌套JSON并提取字符串列表的简单方法
首先注意到你的API返回的是JSONP格式(被callback()包裹),不是标准JSON,这是第一步要处理的核心点。下面是最直接的实现方案:
1. 预处理响应字符串
先剥离包裹在外的callback(和),得到标准JSON字符串:
// 假设responseBody是从API获取的原始响应内容 String pureJson = responseBody.replaceFirst(RegExp(r'^callback\('), '').replaceFirst(RegExp(r'\)$'), '');
2. 解码JSON并提取目标列表
用Dart内置的dart:convert包解码,逐层访问嵌套字段直接取出字符串列表:
import 'dart:convert'; // 解码JSON为Map Map<String, dynamic> decodedJson = jsonDecode(pureJson); // 提取compound对应的字符串列表 List<String> compoundList = List<String>.from(decodedJson['dictionary_terms']['compound']);
3. 完整示例(结合TypeAhead组件)
如果使用flutter_typeahead组件,结合网络请求的完整代码如下:
import 'dart:convert'; import 'package:http/http.dart' as http; import 'package:flutter/material.dart'; import 'package:flutter_typeahead/flutter_typeahead.dart'; // 从API获取数据的方法 Future<List<String>> fetchCompoundList() async { final response = await http.get(Uri.parse('你的API接口地址')); if (response.statusCode == 200) { // 处理JSONP格式 String pureJson = response.body.replaceFirst(RegExp(r'^callback\('), '').replaceFirst(RegExp(r'\)$'), ''); Map<String, dynamic> decodedJson = jsonDecode(pureJson); return List<String>.from(decodedJson['dictionary_terms']['compound']); } else { throw Exception('数据请求失败'); } } // 集成TypeAhead的Widget class CompoundAutoComplete extends StatefulWidget { @override _CompoundAutoCompleteState createState() => _CompoundAutoCompleteState(); } class _CompoundAutoCompleteState extends State<CompoundAutoComplete> { late Future<List<String>> _compoundListFuture; @override void initState() { super.initState(); _compoundListFuture = fetchCompoundList(); } @override Widget build(BuildContext context) { return FutureBuilder<List<String>>( future: _compoundListFuture, builder: (context, snapshot) { if (snapshot.hasData) { return TypeAheadField( suggestionsCallback: (pattern) { // 根据输入关键词过滤列表 return snapshot.data!.where((item) => item.toLowerCase().contains(pattern.toLowerCase())).toList(); }, itemBuilder: (context, suggestion) { return ListTile(title: Text(suggestion)); }, onSuggestionSelected: (suggestion) { // 选中选项后的逻辑 print('已选择: $suggestion'); }, ); } else if (snapshot.hasError) { return Text('加载失败: ${snapshot.error}'); } return CircularProgressIndicator(); }, ); } }
关于JSON Serializable的补充
如果一定要用JSON Serializable,只需正确定义嵌套模型即可,示例如下:
import 'package:json_annotation/json_annotation.dart'; part 'api_response.g.dart'; @JsonSerializable() class ApiResponse { Status status; int total; DictionaryTerms dictionary_terms; ApiResponse({required this.status, required this.total, required this.dictionary_terms}); factory ApiResponse.fromJson(Map<String, dynamic> json) => _$ApiResponseFromJson(json); Map<String, dynamic> toJson() => _$ApiResponseToJson(this); } @JsonSerializable() class Status { int code; Status({required this.code}); factory Status.fromJson(Map<String, dynamic> json) => _$StatusFromJson(json); Map<String, dynamic> toJson() => _$StatusToJson(this); } @JsonSerializable() class DictionaryTerms { List<String> compound; DictionaryTerms({required this.compound}); factory DictionaryTerms.fromJson(Map<String, dynamic> json) => _$DictionaryTermsFromJson(json); Map<String, dynamic> toJson() => _$DictionaryTermsToJson(this); }
运行flutter pub run build_runner build生成序列化代码后,同样先处理JSONP字符串,再通过ApiResponse.fromJson(jsonDecode(pureJson))解析,最终取出apiResponse.dictionary_terms.compound即可。
不过如果只是为了提取这个字符串列表,手动解码的方式更简单直接,无需额外依赖和代码生成步骤。
内容的提问来源于stack exchange,提问作者SherriB
相关产品推荐
相关产品推荐

