如何在Java库中为不使用';你没有一个实用的方法吗?
我已经在这个问题上纠缠了大约一个星期了,我想我会把这个问题写在这里,以澄清我的想法并获得一些指导 我有一个case类,它有一个字段:如何在Java库中为不使用';你没有一个实用的方法吗?,java,scala,playframework,playframework-2.0,Java,Scala,Playframework,Playframework 2.0,我已经在这个问题上纠缠了大约一个星期了,我想我会把这个问题写在这里,以澄清我的想法并获得一些指导 我有一个case类,它有一个字段: case类请求(id:Option[Int],requestDate:Timestamp) 我想把这个转换成一个 “找不到类型列表[models.Request]的Json反序列化程序。请尝试为此类型实现隐式写入或格式。”好的,这很有意义 接下来,我尝试写一个格式 implicit val requestFormat = Json.format[Request]
case类请求(id:Option[Int],requestDate:Timestamp)
我想把这个转换成一个
“找不到类型列表[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
错误1
现在,重载错误消失了,我找到了更多的难题:未找到:value u
我导入了../functional.syntax.\u
就像文档中说的那样!遇到了同样的问题,但进口为他解决了!那为什么?!我认为这可能是Eclipse的问题,并试图播放run
无论如何。。。没有什么变化。好的编译器总是正确的
导入play.api.lib.json.JsPath,将\uuu
更改为JsPath
,并:
错误2
value apply不是对象java.sql.Timestamp的成员
value不适用于对象java.sql.Timestamp的成员
我还尝试改变策略,并为此编写一篇文章,而不是编写格式,而不使用花哨的新combinator(\uuu
)功能,方法如下:
错误3:特征写入是抽象的,无法实例化
错误4:简单表达式的非法开始
在这一点上,我已经不知所措了,所以我要回到我的精神堆栈的其余部分,从我的第一段代码开始报告
我衷心感谢任何能让我摆脱编码痛苦的人这不一定是你需要的apply
或unapply
功能。它是a)一个函数,在给定一些参数的情况下构造您需要的任何类型;b)一个函数,它将该类型的实例转换为值的元组(通常与输入参数匹配)
使用Scala case类免费获得的apply
和unapply
函数恰好可以做到这一点,因此使用它们很方便。但是你可以自己写
通常,您可以使用以下匿名函数执行此操作:
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))
然而!在这种情况下,您会与API的限制相冲突,该限制阻止您使用一个值编写这样的格式。此限制的解释如下。
对你来说,一种可行的方法是这种看起来更复杂的黑客:
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))
现在,当我实际尝试使用JSON()时,我遇到了一个NullPointerException。。。我不会尝试序列化任何空值,即使这不会导致错误?..@MeredithLeu:确保如果读/写/格式引用它们自己或稍后在同一对象中定义的其他具有循环依赖关系的R/W/F,则使用lazyFormat
帮助程序。否则它可以编译,但在运行时提供NPE。我自己也遇到了这个问题。请参阅递归格式定义的处理。但我的模式中没有任何循环依赖项。。。我有其他对象的外键,但没有一个指向后面。如果没有看到更多的代码和堆栈跟踪(可能是另一个问题),很难提供帮助。Scala中的NPE错误通常与类或对象中变量的初始化顺序有关。如果在初始化之前尝试使用一个(即读/写/格式),该值将为null,并在运行时崩溃。是的,这就是我提到的初始化顺序。请求格式是在时间戳格式之前生成的(神奇的是,由宏生成),时间戳格式取决于时间戳格式。我认为您可以将时间戳格式代码粘贴在implicit val requestFormat=Json.format[Request]
行的上方,如果没有lazy
修饰符,它就可以工作了。
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._
// 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()
)
}
)
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))
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))