Flutter使用Retrofit请求报错:'String'不是'Map<String, dynamic>'的子类型
Flutter Retrofit请求错误:
type 'String' is not a subtype of type 'Map<String, dynamic>' 解决方案 问题背景
使用Flutter Retrofit向服务器发起请求时,触发类型转换错误:type 'String' is not a subtype of type 'Map<String, dynamic>'。服务器返回的JSON格式看似合法,但无法自动解析为定义好的响应模型。
相关代码
Api服务类
@RestApi(baseUrl: kBaseUrl) abstract class RecipesApiService { factory RecipesApiService(Dio dio, {String baseUrl}) = _RecipesApiService; @GET('my=endpoint') Future<HttpResponse<AboutResponse>> about(); }
响应模型类
class AboutResponse { final String page; AboutResponse({this.page }); factory AboutResponse.fromJson(Map<String, dynamic> json) { return AboutResponse( page: json['page'] as String, ); } Map<String, dynamic> toJson() { final Map<String, dynamic> data = new Map<String, dynamic>(); data['page'] = page; return data; } }
服务器返回响应
{"page":"\u041e\n\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438"}
解决方向
1. 强制Dio解析响应为JSON
问题核心大概率是服务器返回的Content-Type响应头不是application/json,导致Dio未自动将响应体解析为Map<String, dynamic>,而是保留为String类型。初始化Dio时可强制指定响应类型:
final dio = Dio(); // 强制将响应解析为JSON格式 dio.options.responseType = ResponseType.json;
2. 添加拦截器手动转换响应格式
若服务器无法修改响应头,可通过Dio拦截器手动将String格式的响应体解码为JSON:
import 'dart:convert'; final dio = Dio(); dio.interceptors.add(InterceptorsWrapper( onResponse: (response, handler) { // 若响应体是String类型,手动解码为JSON if (response.data is String) { try { response.data = jsonDecode(response.data); } catch (e) { print('JSON解码失败: $e'); } } handler.next(response); }, ));
3. 禁止手动修改生成的Retrofit代码
不要直接修改Retrofit自动生成的_RecipesApiService类代码,这类代码会在重新生成时被覆盖,所有配置应通过Dio初始化或Retrofit注解完成。
4. 增强模型类解析鲁棒性
可在模型类的fromJson方法中添加空值判断,避免因字段缺失导致的异常:
factory AboutResponse.fromJson(Map<String, dynamic> json) { return AboutResponse( page: json['page']?.toString() ?? '', ); }
内容的提问来源于stack exchange,提问作者Patrick
相关产品推荐
相关产品推荐

