Mer*_*ith 14 java scala playframework playframework-2.0
我已经被困在这个特定的问题上大约一个星期了,我想我会在这里写下这个问题来清除我的想法并得到一些指导.
所以我有这个case类有一个java.sql.Timestamp字段:
case class Request(id: Option[Int], requestDate: Timestamp)
我想将其转换为JsObject
val q = Query(Requests).list // This is Slick, a database access lib for Scala
printList(q)
Ok(Json.toJson(q)) // and this is where I run into trouble
Run Code Online (Sandbox Code Playgroud)
"找不到类型为List [models.Request]的Json反序列化器.尝试为此类型实现隐式写入或格式化." 好的,这是有道理的.
implicit val requestFormat = Json.format[Request] // need Timestamp deserializer
implicit val timestampFormat = (
(__ \ "time").format[Long] // error 1
)(Timestamp.apply, unlift(Timestamp.unapply)) // error 2
Run Code Online (Sandbox Code Playgroud)
Description Resource Path Location Type overloaded method value format with alternatives:
(w: play.api.libs.json.Writes[Long])(implicit r: play.api.libs.json.Reads[Long])play.api.libs.json.OFormat[Long]
<and>
(r: play.api.libs.json.Reads[Long])(implicit w: play.api.libs.json.Writes[Long])play.api.libs.json.OFormat[Long]
<and>
(implicit f: play.api.libs.json.Format[Long])play.api.libs.json.OFormat[Long]
cannot be applied to (<error>, <error>)
Run Code Online (Sandbox Code Playgroud)
显然像这样导入(参见文档 "ctrl + F import")让我陷入困境:
import play.api.libs.json._ // so I change this to import only Format and fine
import play.api.libs.functional.syntax._
import play.api.libs.json.Json
import play.api.libs.json.Json._
Run Code Online (Sandbox Code Playgroud)
现在重载错误消失了,我得到了更多的trubbles:not found: value __
我.../functional.syntax._
已经导入了就像它在文档中所说的那样!这家伙遇到了同样的问题,但导入修复了它!所以为什么?!我认为这可能只是Eclipse的问题并且play run
无论如何都试图......没有任何改变.精细.编译器永远是对的.
导入play.api.lib.json.JsPath,更改__
为JsPath
和wallah:
value apply is not a member of object java.sql.Timestamp
value unapply is not a member of object java.sql.Timestamp
我也尝试更改大头钉并为此写一个Write而不是Format,没有花哨的新组合(__
)功能,遵循官方文档基于/复制粘贴的原始博客文章:
// I change the imports above to use Writes instead of Format
implicit val timestampFormat = new Writes[Timestamp]( // ERROR 3
def writes(t: Timestamp): JsValue = { // ERROR 4 def is underlined
Json.obj(
/* Returns the number of milliseconds since
January 1, 1970, 00:00:00 GMT represented by this Timestamp object. */
"time" -> t.getTime()
)
}
)
Run Code Online (Sandbox Code Playgroud)
错误3:trait Writes is abstract, cannot be instantiated
错误4:illegal start of simple expression
在这一点上,我在我的智慧结束,所以我只是回到我的心理堆栈的其余部分并从我的第一段代码报告
我完全感激任何可以让我摆脱编码痛苦的人
Mik*_*ame 19
It's not necessarily apply
or unapply
functions you need. It's a) a function that constructs whatever the type you need given some parameters, and b) a function that turns an instance of that type into a tuple of values (usually matching the input parameters.)
The apply
and unapply
functions you get for free with a Scala case class just happen to do this, so it's convenient to use them. But you can always write your own.
Normally you could do this with anonymous functions like so:
import java.sql.Timestamp
import play.api.libs.functional.syntax._
import play.api.libs.json._
implicit val timestampFormat: Format[Timestamp] = (
(__ \ "time").format[Long]
)((long: Long) => new Timestamp(long), (ts: Timestamp) => (ts.getTime))
Run Code Online (Sandbox Code Playgroud)
However! In this case you fall foul of a limitation with the API that prevents you from writing formats like this, with only one value. This limitation is explained here, as per this answer.
For you, a way that works would be this more complex-looking hack:
import java.sql.Timestamp
import play.api.libs.functional.syntax._
import play.api.libs.json._
implicit val rds: Reads[Timestamp] = (__ \ "time").read[Long].map{ long => new Timestamp(long) }
implicit val wrs: Writes[Timestamp] = (__ \ "time").write[Long].contramap{ (a: Timestamp) => a.getTime }
implicit val fmt: Format[Timestamp] = Format(rds, wrs)
// Test it...
val testTime = Json.obj("time" -> 123456789)
assert(testTime.as[Timestamp] == new Timestamp(123456789))
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
10057 次 |
最近记录: |