gpt4 book ai didi

java - 如何从 JSON 反序列化为 LocalDate,同时还使用 JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:13:13 25 4
gpt4 key购买 nike

我已启用 jackson-datatype-joda,但它无法与 JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS 一起使用。

我已经按如下方式设置了 ObjectMapper:

ObjectMapper jacksonObjectMapper = new ObjectMapper();
jacksonObjectMapper.configure(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS, true);
jacksonObjectMapper.registerModule(new JodaModule());

反序列化时(使用 com.fasterxml.jackson.datatype.joda.deser.LocalDateDeserializer),我最终遇到错误:

org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Current token (VALUE_STRING) not numeric, can not use numeric value accessors
at [...]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Current token (VALUE_STRING) not numeric, can not use numeric value accessors

我调试了 LocalDateDeserializer 并发现它期望 VALUE_NUMBER_INT - 而 JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS 使日期具有字符串。

当我关闭该功能时,一切正常。

此功能(或类似功能)是否有可能与 Joda Time 一起使用?

最佳答案

Joda 模块使用 com.fasterxml.jackson.datatype.joda.deser.LocalDateDeserializer用于反序列化 org.joda.time.LocalDate 对象。这个类看起来像这样:

@Override
public LocalDate deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
// [yyyy,mm,dd]
if (jp.isExpectedStartArrayToken()) {
jp.nextToken(); // VALUE_NUMBER_INT
int year = jp.getIntValue();
jp.nextToken(); // VALUE_NUMBER_INT
int month = jp.getIntValue();
jp.nextToken(); // VALUE_NUMBER_INT
int day = jp.getIntValue();
if (jp.nextToken() != JsonToken.END_ARRAY) {
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY, "after LocalDate ints");
}
return new LocalDate(year, month, day);
}
switch (jp.getCurrentToken()) {
case VALUE_NUMBER_INT:
return new LocalDate(jp.getLongValue());
case VALUE_STRING:
String str = jp.getText().trim();
if (str.length() == 0) { // [JACKSON-360]
return null;
}
return parser.parseLocalDate(str);
default:
}
throw ctxt.wrongTokenException(jp, JsonToken.START_ARRAY, "expected JSON Array, String or Number");
}

如您所见,如果 LocalDate 是数组,则此反序列化器需要此数组中的整数。您可以编写自定义反序列化器并扩展此实现。请参见以下示例:

class LocalDateWithStringsDeserializer extends LocalDateDeserializer {

private static final long serialVersionUID = 1L;

@Override
public LocalDate deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException,
JsonProcessingException {
// [yyyy,mm,dd] or ["yyyy","mm","dd"]
if (jp.isExpectedStartArrayToken()) {
return parseArray(jp, ctxt);
}

return super.deserialize(jp, ctxt);
}

private LocalDate parseArray(JsonParser jp, DeserializationContext ctxt)
throws JsonParseException, IOException {
int year = getNextValue(jp);
int month = getNextValue(jp);
int day = getNextValue(jp);
if (jp.nextToken() != JsonToken.END_ARRAY) {
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY, "after LocalDate ints");
}
return new LocalDate(year, month, day);
}

private int getNextValue(JsonParser jp) throws IOException, JsonParseException {
jp.nextToken();

return new Integer(jp.getText());
}
}

现在您可以链接上面的反序列化器和您的属性:

@JsonDeserialize(using = LocalDateWithStringsDeserializer.class)
private LocalDate date;

关于java - 如何从 JSON 反序列化为 LocalDate,同时还使用 JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24432828/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com