播放/ Scala JSON格式

Mik*_*inn 7 json scala playframework-2.0

我有一个值类,接受一个Either,我想生成一个Play for Scala v2.5.6 JSON Format:

import org.joda.time.{DateTime, Duration}

case class When(when: Either[DateTime, Duration]) extends AnyVal
Run Code Online (Sandbox Code Playgroud)

我想我已经找到了writes方法; 我遇到的问题是这个reads方法.我试过两种方法,都因为不同的原因而失败了.

尝试#1,显示reads和writes方法:

import play.api.libs.json._
import play.api.libs.json.Json.obj

object When {    
  def apply(dateTime: DateTime): When = When(Left(dateTime))

  def apply(duration: Duration): When = When(Right(duration))

  implicit val whenFormat = new Format[When] {
    def reads(json: JsValue): JsResult[When] = {
      val reads = (__ \ "dateTime").read[Long] { (millis: Long) =>
        When(Left(new DateTime(millis)))
      } | (__ \ "duration").read[Long] { (millis: Long) =>
        When(Right(new Duration(millis)))
      }
      reads.reads(json)
    }

    def writes(o: When): JsValue = obj(
      o.when.fold(
        duration => "duration" -> duration.getMillis,
        dateTime => "dateTime" -> dateTime.getMillis
      )
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

错误消息是:

overloaded method value read with alternatives:
[error]   (t: Long)play.api.libs.json.Reads[Long] <and>
[error]   (implicit r: play.api.libs.json.Reads[Long])play.api.libs.json.Reads[Long]
[error]  cannot be applied to (Long => When)
[error]       val reads = (__ \ "dateTime").read[Long] { (millis: Long) =>

[error] overloaded method value read with alternatives:
[error]   (t: Long)play.api.libs.json.Reads[Long] <and>
[error]   (implicit r: play.api.libs.json.Reads[Long])play.api.libs.json.Reads[Long]
[error]  cannot be applied to (Long => When)
[error]       } | (__ \ "duration").read[Long] { (millis: Long) =>
Run Code Online (Sandbox Code Playgroud)

尝试#2,只显示reads方法:

def reads(json: JsValue): JsResult[When] =
  JsSuccess(
    When(Left(new DateTime((__ \ "dateTime").read[Long]))) ||
    When(Right(new Duration((__ \ "duration").read[Long])))
  )
Run Code Online (Sandbox Code Playgroud)

错误消息是:

value || is not a member of When
[error]  Note: implicit value whenFormat is not applicable here because it comes after the application point and it lacks an explicit result type
[error] Error occurred in an application involving default arguments.
Run Code Online (Sandbox Code Playgroud)

我只是喜欢有用的东西,我不关心使用什么方法(即使是我没有展示的方法),只要它是可维护和有效的.了解每种方法的错误也会有所帮助.

Łuk*_*asz 8

以下是如何执行此操作的工作示例:

import org.joda.time.{DateTime, Duration}
import play.api.libs.functional.syntax._
import play.api.libs.json.Reads._
import play.api.libs.json._

object When {
  def apply(dateTime: DateTime): When = When(Left(dateTime))

  def apply(duration: Duration): When = When(Right(duration))

  val reads: Reads[When] = 
    (__ \ "dateTime").read[Long].map(millis => When(Left(new DateTime(millis)))) |
    (__ \ "duration").read[Long].map(millis => When(Right(new Duration(millis))))

  val writes: Writes[When] = new Writes[When] {
    override def writes(o: When): JsValue = Json.obj(
      o.when.fold(
        duration => "duration" -> duration.getMillis,
        dateTime => "dateTime" -> dateTime.getMillis
      )
    )
  }

  implicit val format = Format(reads, writes)
}
Run Code Online (Sandbox Code Playgroud)

基本上你应该映射读数

(__ \ "dateTime").read[Long]
Run Code Online (Sandbox Code Playgroud)

给你Reads[Long],然后你可以将结果映射到When.你只是传递参数.这个参数可以是a Long,只是忽略读取的内容并返回该值,或者implicit读取你可能不想改变的长时间,并且应该让它保持隐含.

那么以类似的方式你可以创建另一个读取持续时间并将它们与alternative(|)和完成组合,你有读取.

你的第二种方法毫无意义.要么使用读取和组合它们,要么只是手动检查是否有东西,如果没有返回不同的结果,但是不值得这样做,只需采用默认方法.