以特定格式传递查询日期参数

a_s*_*ber 1 android datetime-format retrofit2

在我的 android 应用程序中,我使用 Retrofit 2

@GET("/operations")
    fun getOperationsList(
        @Query("types") typeList: List<@JvmSuppressWildcards OperationType>,
        @Query("status") statusList: List<@JvmSuppressWildcards OperationStatus>,
        @Query("from") from: Date, @Query("to") to: Date
    ): Call<List<Operation>>
Run Code Online (Sandbox Code Playgroud)

这里结果 http 请求:

08-06 15:40:17.672 D/OkHttp  ( 2436): --> GET http://my_ip:8081/operations?types=payment&types=payout&status=executed&from=Tue%20Aug%2006%2015%3A40%3A17%20GMT%2B03%3A00%202019&to=Tue%20Aug%2006%2015%3A40%3A17%20GMT%2B03%3A00%202019 http/1.1
Run Code Online (Sandbox Code Playgroud)

但我需要以from, to这种格式传递日期参数():

YYYY-MM-ddTHH:mm:ss.Z
Run Code Online (Sandbox Code Playgroud)

例子:

https://some_host/operations?types=transfer&types=payment&status=executed&from=2018-07-01T19%3A13%3A51.418Z&to=2019-08-05T11%3A04%3A22.397Z
Run Code Online (Sandbox Code Playgroud)

在 Retrofit 2 中有可能吗?

a_s*_*ber 5

我认为使用自定义转换器 ( QueryConverterFactory) 是更好的解决方案:

 private static Retrofit.Builder builder = new Retrofit.Builder()
            .baseUrl(BuildConfig.API_BASE_URL)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .addConverterFactory(QueryConverterFactory.create())
            .client(httpClient.build());



public class QueryConverterFactory extends Converter.Factory {
    public static QueryConverterFactory create() {
        return new QueryConverterFactory();
    }

    @Override
    public Converter<?, String> stringConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
        if (type == Date.class) {
            return DateQueryConverter.INSTANCE;
        }
        return null;
    }

    private static final class DateQueryConverter implements Converter<Date, String> {
        static final DateQueryConverter INSTANCE = new DateQueryConverter();

        private static final ThreadLocal<DateFormat> DF = new ThreadLocal<DateFormat>() {
            @Override
            public DateFormat initialValue() {
                return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
            }
        };

        @Override
        public String convert(Date date) {
            return DF.get().format(date);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

结果参数保持日期格式。

@GET("/operations")
    fun getOperationsList(
        @Query("types") typeList: List<@JvmSuppressWildcards OperationType>,
        @Query("status") statusList: List<@JvmSuppressWildcards OperationStatus>,
        @Query("from") from: Date, @Query("to") to: Date
    ): Call<List<Operation>>
Run Code Online (Sandbox Code Playgroud)

结果如下:

08-06 16:16:30.883 D/OkHttp  ( 8555): --> GET http://my_host:8081/operations?types=payment&types=payout&status=executed&from=2019-08-06T16%3A16%3A30&to=2019-08-06T16%3A16%3A30 http/1.1
Run Code Online (Sandbox Code Playgroud)