如何在Play中将java.time.LocalDate转换为JSValue?

时间:2015-05-13 13:45:44

标签: json scala playframework

我正在使用Play 2.3.x.代码是将对象写入JSON。

如何将具有java.time.LocalDate字段的模型转换为JSValue?

case class ModelA(id: Int, birthday: LocalDate)

implicit val modelAWrites: Writes[ModelA] = (
    (JsPath \ "id").write[Int] and
    (JsPath \ "birthday").write[LocalDate]
 )(unlift(ModelA.unapply))

编译器抱怨说:

No Json serializer found for type java.time.LocalDate. Try to implement an implicit Writes or Format for this type.

感谢。

4 个答案:

答案 0 :(得分:2)

如果将LocalDate表示为ISO日期字符串(例如"2016-07-09")就足够了,那么格式化程序就变得非常简单了:

  implicit val localDateFormat = new Format[LocalDate] {
    override def reads(json: JsValue): JsResult[LocalDate] =
      json.validate[String].map(LocalDate.parse)

    override def writes(o: LocalDate): JsValue = Json.toJson(o.toString)
  }

这是一个免费测试来证明它:

package com.mypackage

import java.time.LocalDate

import org.scalatest.{Matchers, WordSpecLike}
import play.api.libs.json.{JsString, Json}

class MyJsonFormatsSpec extends WordSpecLike with Matchers {
  import MyJsonFormats._

  "MyJsonFormats" should {
    "serialize and deserialize LocalDates" in {
      Json.toJson(LocalDate.of(2016, 7, 9)) shouldEqual JsString("2016-07-09")
      JsString("2016-07-09").as[LocalDate] shouldEqual LocalDate.of(2016, 7, 9)
    }
  }
}

答案 1 :(得分:1)

Play能够将大多数原始数据类型写入Json,例如Ints,Strings等。但它无法将随机类型写入Json,这是公平的,否则框架必须为任何类型提供一个看起来有点不切实际的序列化器!

所以,Play告诉你它不知道如何序列化java.time.LocalDate类型。您需要教Play如何将LocalDate的实例写入Json。

请点击此处查看有关如何操作的文档:https://www.playframework.com/documentation/2.3.x/ScalaJsonCombinators

答案 2 :(得分:0)

而是使用LocalDate表单java.time.LocalDate使用LocalDate中的org.joda.time.LocalDate或编写自定义隐式

implicit val dateFormat =
      Format[LocalDate](Reads.jodaLocalDateReads(pattern), Writes.jodaLocalDateWrites(pattern))

答案 3 :(得分:0)

我也有这个问题,我通过自己创建ReadsWrites解决了这个问题。

implicit val localDateReads: Reads[LocalDate] = (
  (__ \ "year").read[Int] and
    (__ \ "month").read[Int] and
    (__ \ "day").read[Int]
  ) (LocalDate.of(_,_,_))

implicit val LocalDateWrites = new Writes[LocalDate] {
  def writes(date: LocalDate) = Json.obj(
    "day" -> date.getDayOfMonth,
    "month" -> date.getMonthValue,
    "year" -> date.getYear
  )}

在JSON中,它看起来像这样:

"date": {
    "day": 29,
    "month": 8,
    "year": 1993
}