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

为什么Flutter中Dio接收的JSON响应有时无法自动反序列化

问题原因分析

Dio 默认自动将响应反序列化为 _InternalLinkedHashMap 的前提有两个:

  • 响应头的 Content-Type 字段值包含 application/json
  • Dio 实例配置的 responseType 为默认的 ResponseType.json

你遇到的反序列化行为不一致问题,根源是你用 Rust 编写的接口直接返回序列化后的 JSON 字符串,web 框架默认会给该响应设置 Content-Type: text/plain,Dio 识别到非 JSON 类型的响应头就不会自动反序列化;其他返回了正确 Content-Type 的接口则可以正常转 Map,就出现了时好时坏的情况。

解决方案

方案1:服务端修复(最推荐)

不要在 Rust 接口中手动将响应序列化为 String 返回,直接用框架自带的 JSON 响应构造方法,会自动添加正确的 application/json 响应头。你当前用的是 actix-web 框架,代码修改如下:

#[get("/v1/playlist")]
pub fn user_playlist() -> impl Responder {
    use schema::playlist::dsl::*;
    let connection = config::establish_connection();
    let results = playlist.filter(creator.eq(1))
        .limit(1)
        .load::<QueryPlaylist>(&connection)
        .expect("Error loading posts");
    let res = ApiResponse {
        body: results,
        ..Default::default()
    };
    // 直接返回json响应,框架自动加Content-Type: application/json
    HttpResponse::Ok().json(res)
}

方案2:Dio端全局强制反序列化

如果无法修改服务端代码,可以在Dio端做配置,强制所有响应走JSON反序列化:

方法A:自定义响应转换器

重写Dio的转换器逻辑,忽略响应头的Content-Type判断,强制按JSON解析:

import 'package:dio/dio.dart';

class ForceJsonTransformer extends BackgroundTransformer {
  @override
  Future<dynamic> transformResponse(RequestOptions options, ResponseBody responseBody) async {
    // 强制指定响应类型为JSON
    options.responseType = ResponseType.json;
    // 伪造JSON响应头,触发默认解析逻辑
    options.headers[Headers.contentTypeHeader] = Headers.jsonContentType;
    return super.transformResponse(options, responseBody);
  }
}

// 初始化Dio的时候绑定转换器
final dio = Dio();
dio.transformer = ForceJsonTransformer();

方法B:在拦截器中手动转换

在现有的响应拦截器中增加判断,字符串类型的响应手动转JSON:

import 'dart:convert';

@override
Future onResponse(Response response, ResponseInterceptorHandler handler) async {
  // 手动反序列化字符串类型的JSON响应
  if (response.data is String) {
    try {
      response.data = jsonDecode(response.data as String);
    } catch (_) {
      // 非合法JSON响应保留原内容即可
    }
  }
  Response handleResponse = await autoLogin(response);
  Response handleAccessToken = await handleResponseByCode(handleResponse);
  return super.onResponse(handleAccessToken, handler);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 23:36:04