为案例类播放json读取和默认参数?

时间:2017-06-09 13:25:01

标签: json scala playframework playframework-2.0

我遇到默认参数问题并使用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中提供参数,为什么它没有得到默认值?如何实现我的目标?

3 个答案:

答案 0 :(得分:6)

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

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

答案 1 :(得分:1)

看起来默认参数的支持版本为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 _)

答案 2 :(得分:0)

如果您提供默认值,您是否真的需要案例类中的选项?没有选项,以下代码应该起作用

     <android.support.v7.widget.Toolbar           
         android:layout_width="match_parent"
         android:layout_height="?attr/actionBarSize"
         android:animateLayoutChanges="true"
         android:backgroundTint="@color/colorPrimary"
         android:background="?attr/colorPrimary"
         android:elevation="4dp"
         android:minHeight="?android:attr/actionBarSize"
         app:layout_collapseMode="pin"
         app:layout_scrollFlags="scroll|exitUntilCollapsed"
         app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
         app:popupTheme="@style/AppTheme.PopupOverlay"
         app:titleTextAppearance="@style/Toolbar.TitleText" >

      <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/toolbar_title"
            android:text="Title"
            android:layout_gravity="center"/>

     </android.support.v7.widget.Toolbar>

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

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 _)