繁体   English   中英

自定义序列化和反序列化是使用jackson的scala

[英]Custom serialization and deserialization is scala using jackson

我有一个 JSON 作为字符串,我将其反序列化并实例化为 Scala 的 MyPOJO 案例类。 我的数据是 YYYY-MM-DD 格式,但 POJO createdBy 中的实际属性是 LocalDateTime。

如何在实例化 Pojo 时分配默认时间值 2020-03-02 00:00:00,

序列化应该返回 yyyy-mm-dd 格式。 我的序列化和反序列化格式不同。

case class MyPOJO( @JsonFormat(pattern = "yyyy-mm-dd" ) createdBy :LocalDateTime )

object MyJaxsonP {
  def main(args: Array[String]): Unit = {
    val objectMapper = new ObjectMapper() with ScalaObjectMapper
    objectMapper.findAndRegisterModules()
    objectMapper.registerModule(DefaultScalaModule)
    objectMapper.registerModule(new JavaTimeModule)
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
    objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
    val adminDatasP = objectMapper.readValue[MyPOJO]("{\"createdBy\":\"2020-03-02\"}")
    print(adminDatasP.toString)
  }
}

我尝试过自定义序列化和反序列化,如下所示,但没有工作,说缺少默认构造函数

case class MyPOJO( @JsonDeserialize(using = classOf[CustomDateDeserializer] ) createdBy :LocalDateTime ) 

object CustomDateDeserializer {
  private val formatter = new SimpleDateFormat("dd-MM-yyyy")
}

class CustomDateDeserializer(val t: Class[String]) extends StdDeserializer[String](t) {

  override def deserialize(p: JsonParser, ctxt: DeserializationContext): String = {
    val date = p.getText
    return CustomDateDeserializer.formatter.format(date);
  }
}

需要专家输入如何解决这个问题

但没有工作,说缺少默认构造函数

您收到错误消息,因为如果您愿意,案例类的构造函数没有默认值或空值。 在这种特殊情况下,当您声明case class MyPOJO(createdBy : LocalDateTime) scala 编译器将生成类似的内容(示例可能不太准确,我只想展示一个想法):

class MyPOJO(createdBy : LocalDateTime) extends Product with Serializeble {
  override def hashCode(): Int = ...
  override def equals(oterh: Any): Boolean = ...
  override def toString(): String = ...
  // and other methods, like copy, unaply, tupled etc.
}

object MyPOJO {
  def apply(createdBy : LocalDateTime) = new MyPOJO(createdBy)
}

所以杰克逊将无法创建带有空字段(或更准确地说是null值)的空类实例,然后从源 JSON 注入值。

您可以做什么 - 使用普通类而不是案例类。 或者,更可取的是,看看像Circe这样的 Scala 友好的 JSON 库,它不是基于反射的,与 Jackson 不同,而是在编译时为某些类生成 JSON 编解码器,基于隐式和 Scala 宏(更准确地说,它依赖于在Shapeless使用 Scala 宏机制的Shapeless库)。

在您的特定情况下,代码如下所示:

    import io.circe._
    import io.circe.generic.auto._
    import io.circe.syntax._

    case class MyPOJO(createdBy: LocalDateTime)
    val format = DateTimeFormatter.ofPattern("yyyy-MM-dd")

    // Implement own `Encoder` to render `LocalDateTime` as JSON string, separated with comma inside
    implicit val encoder: Encoder[LocalDateTime] = Encoder[String].contramap(_.format(format))

    // Implement own `Decoder` to parse JSON string as `LocalDateTime`
    implicit val decoder: Decoder[LocalDateTime] = Decoder[String].
      emapTry(value => Try(LocalDate.parse(value, format).atStartOfDay()))

    val foo = MyPOJO(LocalDateTime.now())
    val json = foo.asJson

    println(json.noSpaces)
    println(json.as[MyPOJO])

这将产生下一个结果:

{"createdBy":"2020-03-04"}
Right(MyPOJO(2020-03-04T00:00))

希望这可以帮助!

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM