Flutter解析JSON Placeholder接口报错:List<dynamic>不是String子类型
报错原因
- Dio库默认会自动解析JSON格式的响应数据,你请求的
https://jsonplaceholder.typicode.com/albums接口返回的是JSON数组,请求成功后response.data已经是解析完成的List<dynamic>类型,你额外调用jsonDecode()方法时,该方法要求传入的是JSON格式字符串,传入List<dynamic>就会触发类型不匹配报错。 - 当前代码定义的
fetchData返回值是单个UserModel类型,但接口返回的是包含多条专辑数据的集合,类型定义和实际返回结构不匹配。
修复方案
1. 适配列表返回的修改方案
修改Http请求类
调整返回值类型为列表,移除多余的jsonDecode调用,遍历解析列表数据为UserModel集合:
class HttpService { final url = "https://jsonplaceholder.typicode.com/albums"; late Dio _dio; HttpService(){ _dio = Dio(); } // 返回值改为List<UserModel> Future<List<UserModel>> fetchData() async { var response = await _dio.get(url); // 移除jsonDecode,直接遍历response.data生成模型列表 return (response.data as List).map((item) => UserModel.fromJson(item)).toList(); } }
修改首页代码
调整FutureBuilder泛型适配列表返回值,修改页面逻辑展示列表数据:
class HomeScreen extends StatefulWidget { const HomeScreen({Key? key}) : super(key: key); @override _HomeScreenState createState() => _HomeScreenState(); } class _HomeScreenState extends State<HomeScreen> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("Http Requests"), ), // 泛型改为List<UserModel> body: FutureBuilder<List<UserModel>>( future: HttpService().fetchData(), builder: (context, snapshot) { if (!snapshot.hasData) { return const Center( child: CircularProgressIndicator(), ); } else { // 用ListView展示所有专辑数据 return ListView.builder( itemCount: snapshot.data!.length, itemBuilder: (context, index) { final album = snapshot.data![index]; return ListTile( title: Text(album.title), subtitle: Text("用户ID:${album.userId},专辑ID:${album.id}"), ); }, ); } }, ), ); } }
2. 仅需要单条数据的修改方案
如果业务只需要获取单条专辑数据,可将请求地址改为单条数据接口,保持原有返回单个UserModel的逻辑即可,只需移除多余的jsonDecode调用:
Future<UserModel> fetchData() async { var response = await _dio.get("https://jsonplaceholder.typicode.com/albums/1"); return UserModel.fromJson(response.data); }
内容的提问来源于stack exchange,提问作者Haree Prasad
相关产品推荐
相关产品推荐

