问题的简短故事在标题中。有一些Java类,例如org.joda.time.Interval,我想(不重写它)使其成为案例类,即具有apply
和unapply
方法。是否有可能为现有的Java bean类获取Scala案例类?
长的故事:我有一个Scala的播放应用程序,有我定义的形式,需要两个区间,即
import org.joda.time.Interval
case class MyParams(param1: String, interval1: Interval, interval2: Interval)
,然后我试图定义嵌套映射,但Interval
是一个Java类,并没有按”没有apply
/unapply
,我宁愿不创建我自己的副本。
val myForm = Form {
mapping(
"param1" -> nonEmptyText,
"interval1" -> mapping(
"start" -> jodaDate,
"end" -> jodaDate,
)(Interval.apply)(Interval.unapply), // <<<<<<<<<< Cannot resolve symbol ...
"interval2" -> mapping(
"start" -> jodaDate,
"end" -> jodaDate,
)(Interval.apply)(Interval.unapply) // <<<<<<<<<< Cannot resolve symbol ...
)(MyParams.apply)(MyParams.unapply)
}
当然,我可以扁平化结构,但这样做不会很好地扩展设计方面再加上有,将需要组成现有JSON复合材料结构,我想重用绑定到窗体这两个JSON请求和表单提交。作为补充
object IntervalUtils {
implicit object Interval {
def apply(start: DateTime, end: DateTime) = new org.joda.time.Interval(start, end)
def unapply(interval: org.joda.time.Interval) = Some((interval.getStart, interval.getEnd))
}
}
所以OP的代码编译为只缺少import IntervalUtils._
然后:
UPDATE建设上公认的答案的顶部,并采取语法糖顾及我在最后做奖金也可以这样做:
implicit val jodaIntervalWrites = new Writes[org.joda.time.Interval] {
def writes(interval: org.joda.time.Interval) = Json.obj(
"start" -> interval.getStart,
"end" -> interval.getEnd
)
}
implicit val jodaIntervalReads: Reads[org.joda.time.Interval] = (
(JsPath \ "start").read[DateTime] and
(JsPath \ "end").read[DateTime]
)(Interval.apply _) // <<<<<<<<<<<<<<<<<< reused here