【问题标题】:How to ignore (skip deserialisation) for a malformed LocalDate field in Kotlin?如何在 Kotlin 中忽略(跳过反序列化)格式错误的 LocalDate 字段?
【发布时间】:2021-06-03 00:55:28
【问题描述】:

我有Micronaut Http ClientKotlin,它从另一个微服务加载数据。此微服务的日期格式有时无效。

示例:正常模式为dd-MM-yyyy,但当没有日期时,微服务将其返回为" - - "。所以,当日期为" - - " 时,我需要跳过序列化。我已经使用了@JsonDeserialize(using = "CustomDateDeserialize"),但是当不满足模式时,我无法不反序列化日期字段。

我的客户

@Get(value = ..., produces = [MediaType.APPLICATION_JSON])
@Headers(...)
fun findParcels(...) : HttpResponse<MyDTO>

MyDTO

@KotlinBuilder
data class ParcelsDTO(
   @JsonProperty("property1")
   val property1: String
   
   @JsonProperty("property2")
   val property2: Long
   
   @JsonProperty("property3")
   @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy")
   val property3: LocalDate
   
   @JsonProperty("property4")
   val property4: BigDecimal
   
   @JsonProperty("property5")
   @JsonDeserialize(using = CustomLocalDateDeserializer::class)
   @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy")
   val property5: LocalDate
)

MyCustomDeserializer

class CustomLocalDateDeserializer protected constructor() : StdDeserializer<LocalDate?>(LocalDate::class.java) {
    @Throws(IOException::class)
    override fun deserialize(parser: JsonParser, context: DeserializationContext?): LocalDate {
        val node: JsonNode = parser.codec.readTree(parser)

        val itemName = node.get("property5").asText()

        if(!GenericValidator.isDate(itemName, "dd-MM-yyyy", true)){
            //here was to set to not serialize the node
        }

        return LocalDateDeserializer.INSTANCE.deserialize(parser, context)
    }
}

源 Json

{
   [
      {
         "property1": "string",
         "property2": 123,
         "property3": "01-01-2021",
         "property4": 1.20,
         "property5": " - - ",
      },
      {
         "property1": "string2",
         "property2": 123,
         "property3": "01-01-2021",
         "property4": 1.20,
         "property5": "01-01-2022",
      },   
   ]
}

【问题讨论】:

  • 发布您的自定义反序列化代码
  • @yejianfengblue 我正在添加我的自定义解串器并设置在我的 DTO 中。
  • 尝试从property5 中删除@JsonFormat。 null 是否在 if (!GenericValidator... 代码块中返回?调试格式错误的日期时,是否进入if代码块?
  • 如果要反序列化的源 Json 不满足所需格式,我如何为日期定义 JsonFormat Jackson 返回异常,我想要的是对于不满足模式的情况,节点从反序列化中删除。对于 if 块 (!GenericValidator... 它需要我返回一个特定的日期(一个实例化的 LocalDate 对象),这将在我的 DTO 中反映一个不存在的日期,获得 JsonIgnore 行为的意图其中默认不同,即如果日期“dd-MM-yyyy”返回一个LocalDate,否则JsonIgnore这个字段

标签: json kotlin jackson deserialization micronaut-client


【解决方案1】:

您的自定义反序列化器做的比它必须做的更多。您只需要处理日期值。看看它应该是什么样子:

import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.BeanProperty
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.JsonDeserializer
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer
import java.io.IOException
import java.time.LocalDate
import java.time.format.DateTimeFormatter

class CustomLocalDateDeserializer : LocalDateDeserializer(DateTimeFormatter.ofPattern("dd-MM-yyyy")) {

    @Throws(IOException::class)
    override fun deserialize(parser: JsonParser, context: DeserializationContext?): LocalDate {
        val value: String? = parser.text

        if (value == null || value == " - - ") {
            // skip deserialisation and return default date
            return LocalDate.of(2000, 1, 1)
        }
        return super.deserialize(parser, context)
    }

    override fun createContextual(ctxt: DeserializationContext?, property: BeanProperty?): JsonDeserializer<*> {
        return this
    }
}

您可以按如下方式注册:

@JsonProperty("property5")
@JsonDeserialize(using = CustomLocalDateDeserializer::class)
val property5: LocalDate

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-22
    • 1970-01-01
    • 2012-06-29
    • 1970-01-01
    • 2015-09-01
    • 1970-01-01
    相关资源
    最近更新 更多