unable to understand why validateOpt will return `

2019-08-17 12:09发布

In the following code, I am unable to understand why validateOpt might return value JsSuccess(None) instead of JsError

def getQuestion = silhouette.UserAwareAction.async{ 

    implicit request => {        
      val body: AnyContent = request.body
      val jsonBodyOption: Option[JsValue] = body.asJson

      jsonBodyOption.map((jsonBody:JsValue) => { //body is json
        val personJsonJsResultOption = jsonBody.validateOpt[Person]//check that json structure is correct

        personJsonJsResultOption match {
          case personSuccessOption: JsSuccess[Option[Person]] => { //json is correct
val personOption = personSuccessOption.getOrElse(None) //why would getOrElse return None??
            personOption match {
              case Some(person) => {
...              }
              case None =>{ //I am not sure when this will be triggered.
     ...
                }
              }
            }
          }
          case e: JsError => {
        ...
            }
          }
        }
      })
      .getOrElse(//body is not json
...)
    }
  }

1条回答
放我归山
2楼-- · 2019-08-17 12:43

validateOpt by design considers success to be not only when body provides actual Person but also when Person is null or not provided. Note how documentation explains why JsSuccess(None) is returned:

  /**
   * If this result contains `JsNull` or is undefined, returns `JsSuccess(None)`.
   * Otherwise returns the result of validating as an `A` and wrapping the result in a `Some`.
   */
  def validateOpt[A](implicit rds: Reads[A]): JsResult[Option[A]]

Seems like your requirement is that Person must always be provided to be considered successful, so in this case validate should be used instead of validateOpt.

查看更多
登录 后发表回答