我有一个 JSON 作为字符串,我将其反序列化并实例化为 scala 的 MyPOJO 案例类。我的数据是 YYYY-MM-DD 格式,但 POJO createBy 中的实际属性是 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);
}
}
需要专家提供有关如何解决此问题的意见
最佳答案
but is not working saying default constructor is missing
您收到错误,因为案例类没有默认或空的构造函数(如果您愿意的话)。在这种特殊情况下,当您声明 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)
}
因此 Jackson 将无法创建具有空字段(或更准确地说是 null
值)的空类实例,然后从源 JSON 注入(inject)值。
你可以做什么 - 使用普通类而不是案例类。或者,更可取的是查看 Scala 友好的 JSON 库,例如 Circe与 Jackson 不同,它不是基于反射的,而是基于隐式宏和 Scala 宏在编译时为某些类生成 JSON 编解码器(更准确地说,它依赖于在幕后使用 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))
希望这有帮助!
关于java - 自定义序列化和反序列化是使用 jackson 的 scala,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60501503/