【问题标题】:Play json Read and Default parameters for case class?播放案例类的json读取和默认参数?
【发布时间】:2017-11-11 13:04:06
【问题描述】:

我在使用默认参数和使用 Play Json Read 时遇到问题。 这是我的代码:

  case class Test(action: String, storeResult: Option[Boolean] = Some(true), returndata: Option[Boolean] = Some(true))

  val json =
    """
      {"action": "Test"}"""

  implicit val testReads: Reads[Test] =
    (
      (JsPath \\ "action").read[String](minLength[String](1)) and
        (JsPath \\ "store_result").readNullable[Boolean] and
        (JsPath \\ "returndata").readNullable[Boolean]
      ) (Test.apply _)
  val js = Json.parse(json)

  js.validate[Test] match {
    case JsSuccess(a, _) => println(a)
    case JsError(errors) =>
      println("Here")
      println(errors)
  }

我希望最后得到的是

Test("Test", Some(true), Some(true))

但我得到了:

Test("Test",None,None)

为什么会这样?如果我没有在 json 中提供参数,为什么它没有默认值?如何实现我想要的?

【问题讨论】:

    标签: json scala playframework playframework-2.0


    【解决方案1】:

    在 Play 2.6 中你可以简单地写:

    Json.using[Json.WithDefaultValues].reads[Test]
    

    【讨论】:

    • 这是Play-Json 2.6.x最合适的答案
    【解决方案2】:

    似乎支持默认参数的版本是2.6

    以前版本的解决方法是执行以下操作:

    object TestBuilder {
      def apply(action: String, storeResult: Option[Boolean], returndata: Option[Boolean]) =
        Test(
          action, 
          Option(storeResult.getOrElse(true)), 
          Option(returndata.getOrElse(true))
        )
    }
    
    implicit val testReads: Reads[Test] =
      (
        (JsPath \\ "action").read[String](minLength[String](1)) and
        (JsPath \\ "store_result").readNullable[Boolean] and
        (JsPath \\ "returndata").readNullable[Boolean]
      )(TestBuilder.apply _)
    

    【讨论】:

      【解决方案3】:

      如果您提供默认值,您真的需要在您的案例类中使用选项吗?如果没有选项,以下代码应该可以工作

      case class Test(action: String, storeResult: Boolean = true, returndata: Boolean = true)
      
        implicit val testReads: Reads[Test] =
          (
            (JsPath \\ "action").read[String](minLength[String](1)) and
              ((JsPath \\ "store_result").read[Boolean]  or Reads.pure(true)) and
              ((JsPath \\ "returndata").read[Boolean] or Reads.pure(true))
            ) (Test.apply _)
      

      如果您需要选项,则此代码可能有效(未经测试!)

      case class Test(action: String, storeResult: Option[Boolean] = Some(true), returndata: Option[Boolean] = Some(true))
      
      
        implicit val testReads: Reads[Test] =
          (
            (JsPath \\ "action").read[String](minLength[String](1)) and
              ((JsPath \\ "store_result").read[Boolean]  or Reads.pure(true)).map(x=>Some(x)) and
              ((JsPath \\ "returndata").read[Boolean] or Reads.pure(true)).map(x=>Some(x))
            ) (Test.apply _)
      

      【讨论】:

      • 愚蠢的问题。我收到错误消息“值或不是 play.api.libs.functional 的成员”。想法?
      猜你喜欢
      • 2015-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多