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

Flutter Retrofit中DateTime参数的ISO 8061序列化实现方案

解决Flutter Retrofit中DateTime参数序列化为ISO 8601格式的问题

我来帮你搞定这个DateTime参数的序列化需求,结合flutter_retrofit(基于Dio)的特性,有两种非常实用的方案,我给你详细拆解下:

方案一:自定义参数转换器(推荐,精准控制)

flutter_retrofit支持为单个Query参数指定自定义转换器,专门处理DateTime到ISO 8601字符串的转换,这是最贴合需求的方式。

步骤1:实现DateTime转换器

创建一个类实现Converter<DateTime, String>接口,负责把DateTime转成标准的ISO 8601格式字符串:

import 'package:retrofit/retrofit.dart';

class DateTimeConverter implements Converter<DateTime, String> {
  @override
  String convert(DateTime value) {
    // 直接调用DateTime的toIso8601String()方法即可生成目标格式
    return value.toIso8601String();
  }
}

步骤2:在Retrofit接口中使用转换器

注意:你原来的@Headers中写动态authKey是行不通的——@Headers注解的内容是编译时固定的,不能引用变量。所以要把Authorization改为动态的@Header参数传递。修改后的接口如下:

import 'package:dio/dio.dart';
import 'package:retrofit/retrofit.dart';

@RestApi(baseUrl: "https://address.com")
abstract class UserApi {
  factory UserApi(Dio dio, {String baseUrl}) = _UserApi;

  @GET("/users")
  @Headers({
    "Accept": "application/json",
  })
  Future<List<User>> getUsers(
    // 为每个DateTime参数指定自定义转换器
    @Query("fromDate", converter: DateTimeConverter()) DateTime from,
    @Query("toDate", converter: DateTimeConverter()) DateTime to,
    // 动态传递Authorization头部
    @Header("Authorization") String authorization,
  );
}

步骤3:生成并调用接口

修改完接口后,重新运行Retrofit的代码生成命令:

flutter pub run build_runner build --delete-conflicting-outputs

调用时传入动态的Authorization值:

final dio = Dio();
final userApi = UserApi(dio);

// 构造认证字符串
final authKey = "your_base64_encoded_auth_string";
final authorizationHeader = "Basic $authKey";

// 调用接口
final users = await userApi.getUsers(
  DateTime(2021, 2, 21, 12),
  DateTime(2021, 2, 27, 12),
  authorizationHeader,
);

方案二:全局Dio拦截器(批量处理)

如果你希望所有DateTime类型的Query参数都自动转成ISO 8601格式,可以用Dio的拦截器统一处理,不用逐个参数加转换器。

步骤1:实现DateTime拦截器

创建一个拦截器,在请求发送前遍历所有Query参数,把DateTime类型的值转成目标字符串:

import 'package:dio/dio.dart';

class DateTimeQueryInterceptor extends Interceptor {
  @override
  void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
    // 遍历并处理所有Query参数
    options.queryParameters.forEach((key, value) {
      if (value is DateTime) {
        options.queryParameters[key] = value.toIso8601String();
      }
    });
    super.onRequest(options, handler);
  }
}

步骤2:为Dio添加拦截器

创建Dio实例时添加这个拦截器,之后所有通过该Dio实例发起的请求都会自动处理DateTime参数:

final dio = Dio();
// 添加全局拦截器
dio.interceptors.add(DateTimeQueryInterceptor());

final userApi = UserApi(dio);

// 调用接口时无需额外处理DateTime参数
final users = await userApi.getUsers(
  DateTime(2021, 2, 21, 12),
  DateTime(2021, 2, 27, 12),
  "Basic $authKey",
);

两种方案对比

  • 自定义转换器:精准控制单个参数的转换逻辑,适合只需要处理特定参数的场景,代码可读性更强。
  • 全局拦截器:一次性处理所有DateTime类型的Query参数,适合项目中有大量DateTime参数需要统一转换的场景。

内容的提问来源于stack exchange,提问作者kosiara - Bartosz Kosarzycki

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 08:57:43