是否有更简单的方法来强制执行长度>反序列化数组时为0?

时间:2018-03-09 05:11:58

标签: kotlin jackson2 jackson-databind

假设我收到一些看起来像这样的JSON:

{
    "class": "TimesContainer",
    "times": ["08:00", "09:15", "12:30"]
}

可能还有其他一些领域,但我正在简化这个问题。我想将此JSON反序列化为以下类的对象:

class TimesContainer(
    @JsonProperty("times")
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "HH:mm")
    @JsonDeserialize(using = LocalTimeListDeserializer::class)
    val timesOfDay: List<LocalTime>
) {
    //Other code here
}

我的要求是使用LocalTime的自然顺序对timesOfDay列表进行排序,并且列表不为空。

到目前为止,我有一个自定义反序列化器,专门用于LocalTime列表:

   class LocalTimeListDeserializer(private val formatter: DateTimeFormatter? = null)
    : StdDeserializer<List<LocalTime>>(List::class.java), ContextualDeserializer {

    @Throws(JsonMappingException::class)
    override fun createContextual(context: DeserializationContext, property: BeanProperty): JsonDeserializer<*> {
        val format: JsonFormat.Value? = findFormatOverrides(context, property, handledType())
        if (format != null) {
            if (format.hasPattern()) {
                val pattern = format.pattern
                return LocalTimeListDeserializer(DateTimeFormatter.ofPattern(pattern))
            }
        }
        return this
    }

    override fun deserialize(parser: JsonParser, context: DeserializationContext): List<LocalTime>? {
        val formatter = this.formatter ?: DateTimeFormatter.ISO_LOCAL_TIME

        if (parser.currentTokenId == JsonTokenId.ID_START_ARRAY) {
            val list: MutableList<LocalTime> = mutableListOf()
            while (parser.nextToken() != JsonToken.END_ARRAY)  {
                if (parser.currentToken == JsonToken.VALUE_STRING) {
                    try {
                        list.add(LocalTime.parse(parser.valueAsString, formatter))
                    } catch (dtpe: DateTimeParseException) {
                        throw context.weirdStringException(parser.valueAsString, LocalTime::class.java, dtpe.message).initCause(dtpe)
                    }
                } else {
                    throw context.wrongTokenException(parser, LocalTime::class.java, JsonToken.VALUE_STRING, "Invalid time of day")
                }
            }

            if (list.isEmpty()) {
                throw context.reportInputMismatch(List::class.java, "TimesContainer requires at least one time of day")
            }

            return list.sorted()
        } else {
            throw context.wrongTokenException(parser, List::class.java, JsonToken.START_ARRAY, "Invalid list of times of day")
        }
    }
}

我正在寻找一种更简单的方法来强制列表非空。我可以在TimesContainer的构造函数中对列表进行排序。

在之前的尝试中,我在TimesContainer的构造函数中引发了一个异常,但是这导致了一个InvalidDefinitionException,这意味着类定义有问题。因此,我认为这不是正确的方法,因为类定义是正确的。

我还考虑在反序列化后单独验证列表,但我意识到这意味着我不再利用Jackson来准确告知用户他们的JSON错误。

到目前为止,我正在使用以下库:

  • com.fasterxml.jackson.module:杰克逊 - 模块科特林:2.9 +
  • com.fasterxml.jackson.datatype:杰克逊 - 数据类型-jsr310:2.9 +

我已经检查了https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotationshttps://github.com/FasterXML/jackson-databind/wiki/Databind-Annotations,试图找到一个可能对此有所帮助的注释,但我很难过。

0 个答案:

没有答案