简体   繁体   English

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

[英]How to deserialize from JSON to LocalDate, while also using JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS?

I have enabled jackson-datatype-joda , but it's not working with the JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS . 我已启用jackson-datatype-joda ,但它不能使用JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS

I have set up ObjectMapper as following: 我已经设置了ObjectMapper如下:

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

When deserializing (using com.fasterxml.jackson.datatype.joda.deser.LocalDateDeserializer ), I end up with the error: 反序列化时(使用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

I've debugged the LocalDateDeserializer and found out, that it's expecting VALUE_NUMBER_INT - while the JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS makes the date having Strings. 我调试了LocalDateDeserializer并发现它期望VALUE_NUMBER_INT - 而JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS使日期具有字符串。

When I've turned off that Feature, everything was all right. 当我关闭该功能时,一切都很好。

Is there any possibility that this feature (or similar) will work with Joda Time? 这个功能(或类似的)有可能与Joda Time一起使用吗?

Joda module uses com.fasterxml.jackson.datatype.joda.deser.LocalDateDeserializer for deserializing org.joda.time.LocalDate objects. Joda模块使用com.fasterxml.jackson.datatype.joda.deser.LocalDateDeserializer来反序列化org.joda.time.LocalDate对象。 This class looks like this: 这个类看起来像这样:

@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");
}

As you can see, if LocalDate is array this deserializer expects ints in this array. 如您所见,如果LocalDate是数组,则此反序列化器需要此数组中的整数。 You can write your custom deserializer and extend this implementation. 您可以编写自定义反序列化程序并扩展此实现。 See below example: 见下面的例子:

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());
    }
}

Now you can link above deserializer and your property: 现在您可以链接上面的反序列化器和您的属性:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 Jackson JsonGenerator 将列表添加到 JSON - how to add a List to JSON using Jackson JsonGenerator 如何编写 JsonGenerator 的输出? - How to write output of JsonGenerator? 你如何通过Jackson的JsonGenerator编写原始JSON? - How can you write raw JSON through Jackson's JsonGenerator? JSONGenerator 如何在 JSON 中输出一个对象 - JSONGenerator How to output an object in the JSON 使用 JsonGenerator 将字符串映射到 JSON - Map a String into JSON using JsonGenerator 如何使用Locale将三个数字解析为LocalDate? - How to parse three numbers to a LocalDate using a Locale? 从浮点/双精度反序列化 LocalDate - Deserialize LocalDate from float/double 如何避免在使用Jackson时反序列化来自JSON字符串的空JSON数组元素 - How to avoid deserialize empty JSON Array elements from JSON String while using Jackson 如何为某些字段禁用Jackson序列化功能WRITE_NUMBERS_AS_STRINGS? - How to disable Jackson serialization feature WRITE_NUMBERS_AS_STRINGS for certain field? 我如何使用 REST controller GET 将 LocalDateTime 反序列化为 LocalDate,其中响应值为 LocalDateTime,DTO 中的值为 LocalDate? - How i can deserialize LocalDateTime into LocalDate using a REST controller GET where value in response is LocalDateTime, value in DTO is LocalDate?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM