2

我已经按照 Scala文档实现了一个类

case class Creature(
  name: String, 
  isDead: Boolean, 
  weight: Float,
  dob: java.sql.Date
)

import play.api.libs.json._
import play.api.libs.functional.syntax._

implicit val creatureFormat = (
  (__ \ "name").format[String] and
  (__ \ "isDead").format[Boolean] and
  (__ \ "weight").format[Float] and
  (__ \ "dob").format[java.sql.Date]
)(Creature.apply, unlift(Creature.unapply))

然后我像这样调用 json 包装器Json.toJson(Creature("John Doe", false, 100.0, new java.sql.Date(1363456800000)))并期望看到类似{"name": "John Doe", "isDead": false, "weight": 100.0, "dob": "2013-03-17" }的输出。相反,我得到的输出类似于{"name": "John Doe", "isDead": false, "weight": 100.0, "dob": 1363456800000 }

请注意,在数据库中,我可以看到出生日期为 2013-03-17。

4

3 回答 3

1

这是我解决它的方法(我明确定义了应用取消应用方法)

val sdf = new java.text.SimpleDateFormat("yyyy-MM-dd")
implicit val creatureFormat = (
  (__ \ "name").format[String] and
  (__ \ "isDead").format[Boolean] and
  (__ \ "weight").format[Float] and
  (__ \ "dob").format[String])
    (((name, isDead, weight, dob) => Creature(name, isDead, weight, new java.sql.Date(sdf.parse(dob).getTime()))),
    unlift((cr: Creature) => Some(cr.name, cr.isDead, cr.weight, sdf.format(cr.dob))))

不知道有没有更好的解决办法。

更新

最后,我为 java.sql.Date 实现了一个格式化程序

import play.api.libs.json._
import play.api.libs.functional.syntax._
import play.api.data.validation.ValidationError
import play.api.libs.json.{ Json => PlayJson, _ }

case class Creature(
  name: String, 
  isDead: Boolean, 
  weight: Float,
  dob: java.sql.Date
)

implicit val sqlDateWrite = new Format[SqlDate] {
  def reads(json: JsValue) = json match {
    case JsString(d) => {
      val theDate = new SqlDate(sdf.parse(d).getTime)
      if (d.matches(sdfPattern) && theDate.compareTo(new Date(0)) > 0) JsSuccess(new SqlDate(sdf.parse(d).getTime))
      else JsError(Seq(JsPath() -> Seq(ValidationError("validate.error.expected.date.in.format(dd-MM-yyyy)"))))
    }
    case _ => JsError(Seq(JsPath() -> Seq(ValidationError("validate.error.expected.date.in.String"))))
  }

  def writes(sd: SqlDate): JsValue = JsString(sdf.format(sd))
}

implicit val creatureFormat = PlayJson.format[Creature]

现在,这两条线都有效

val mcJson = PlayJson.toJson(Creature("John Doe", false, 100, new SqlDate(1368430000000L)))
val mcObj = PlayJson.fromJson[Creature](PlayJson.obj("name"-> "Abul Khan", "isDead"-> true, "weight"-> 115, "dob"-> "17-05-2011")).getOrElse(null)
于 2013-05-07T11:32:08.793 回答
1

默认情况下,java.util.Date Json 序列化程序会生成一个包含日期时间戳的数字。

或者,您可以使用日期序列化程序来生成包含日期表示的字符串。但是,由于 JSON 中没有标准的日期表示,因此您必须明确提供用于生成文本表示的模式:

implicit val creatureFormat = (
  (__ \ "name").format[String] and
  (__ \ "isDead").format[Boolean] and
  (__ \ "weight").format[Float] and
  (__ \ "dob").format(sqlDateWrites("YYYY-MM-DD"))(sqlDateReads("YYYY-MM-DD"))
)(Creature.apply, unlift(Creature.unapply))
于 2013-05-15T10:20:44.150 回答
0

由于您期望字符串,因此您必须将所有内容都转换为字符串并丢失输入。

Json.toJson(
  Creature(
    "John Doe", "false", "100.0",(new java.sql.Date(1363456800000)).toString
  )
)
于 2013-05-07T10:48:52.147 回答