Retrofit:2.0.0-beta2,带有 Joda DateTime 的 JacksonConverter

Retrofit:2.0.0-beta2, JacksonConverter with Joda DateTime

我正在尝试将 Retrofit2 与 Jackson 转换器和 Joda DateTime 一起使用。我的代码如下:

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JodaModule());
retrofit = new Retrofit.Builder()
        .baseUrl(RestServiceApi.BASE_URL)
        .addConverterFactory(JacksonConverterFactory.create(mapper))
        .client(okHttpClient)
        .build();

但是没有使用 Joda serializer/deserializer 导致

{
    ...........
    "DateTime": {
         "centuryOfEra": 20,
         "dayOfMonth": 29,
         "dayOfWeek": 2,
         "dayOfYear": 363,
         "era": 1,
         "hourOfDay": 8,
         .....
    }
 }

在不使用 ObjectMapper

的情况下使用 JacksonConverterFactory.create() 可获得相同的结果
   .addConverterFactory(JacksonConverterFactory.create())

如果直接使用同一个 ObjectMapper 将值写入 String,一切都按预期工作。

    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new JodaModule());
    String payload = mapper.writeValueAsString(message);

我们将不胜感激。

编辑: 依赖项:

+--- com.squareup.okhttp:okhttp:2.7.0
|    \--- com.squareup.okio:okio:1.6.0
+--- com.squareup.okhttp:logging-interceptor:2.7.0
|    \--- com.squareup.okhttp:okhttp:2.7.0 (*)
+--- com.squareup.retrofit:retrofit:2.0.0-beta2
|    \--- com.squareup.okhttp:okhttp:2.5.0 -> 2.7.0 (*)
+--- com.squareup.retrofit:converter-jackson:2.0.0-beta2
|    +--- com.squareup.retrofit:retrofit:2.0.0-beta2 (*)
|    \--- com.fasterxml.jackson.core:jackson-databind:2.4.3
|         +--- com.fasterxml.jackson.core:jackson-annotations:2.4.0
|         \--- com.fasterxml.jackson.core:jackson-core:2.4.3
+--- com.fasterxml.jackson.datatype:jackson-datatype-joda:2.4.3
|    +--- com.fasterxml.jackson.core:jackson-annotations:2.4.0
|    +--- com.fasterxml.jackson.core:jackson-core:2.4.3
|    +--- com.fasterxml.jackson.core:jackson-databind:2.4.3 (*)
|    \--- joda-time:joda-time:2.2 -> 2.3
+--- com.box:json-schema-validator:2.2.10
|    +--- joda-time:joda-time:2.3

Edit2: 我删除了 joda-time:2.3 依赖项没有结果。

即使使用 Retrofit2.0-beta3,我也无法使上面的代码工作。

我最终在 DateTime 类型的每个字段上使用显式 serializer/deserializer:

@JsonProperty("DateTime")
@NotNull
@JsonDeserialize(using = CustomDateTimeDeserializer.class)
@JsonSerialize(using = CustomDateTimeSerializer.class)
private Date DateTime;

序列化程序代码:

public class CustomDateTimeSerializer extends StdScalarSerializer<DateTime> {

public CustomDateTimeSerializer() {
    super(DateTime.class);
}

@Override
public void serialize(DateTime dateTime,
                      JsonGenerator jsonGenerator,
                      SerializerProvider provider) throws IOException, JsonGenerationException {
    DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss").withZone(DateTimeZone.forID("Europe/London"));
    String dateTimeAsString = fmt.print(dateTime);
    jsonGenerator.writeString(dateTimeAsString);
}

}

解串器代码:

public class CustomDateTimeDeserializer extends StdScalarDeserializer<DateTime> {

public CustomDateTimeDeserializer() {
    super(DateTime.class);
}

@Override
public DateTime deserialize(JsonParser jsonParser,
                            DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
    JsonToken currentToken = jsonParser.getCurrentToken();
    if (currentToken == JsonToken.VALUE_STRING) {
        String dateTimeAsString = jsonParser.getText().trim();
        DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss").withZone(DateTimeZone.forID("Europe/London"));
        DateTime result = fmt.parseDateTime(dateTimeAsString);
        return result;
    }
    throw deserializationContext.mappingException(getValueClass());
}

}