具有空字符串验证的Play2.1 JSON格式

时间:2013-03-15 15:20:00

标签: json scala playframework-2.1

我正在尝试在解组Play2.1中的对象时验证JSON。我定义的Format对象仅在JSON中缺少字段时验证,但我想验证字段是否为nonEmpty字符串。这可能吗?我已经尝试在reads()调用中指定minLength()约束(如here所示),但是我收到编译器错误,说找不到minLength。这只是为了元组方法吗?

请参阅以下Specs2 Junit测试,该测试现在失败,但应在正确定义约束时通过:

import org.specs2.mutable._
import play.api.libs.json._

class SimpleValidation extends SpecificationWithJUnit{

  private val badPayload: JsValue = Json.obj(
    "simpleValue1" -> "mySimpleValue", // Comment this line out to pass test
    "simpleValue2" -> ""
  )

  "An IssueFormat" should {
    "validate when unmarshalling" in {

      badPayload.validate[SimpleObj].fold(
        valid = (res => {
          // Fail if valid
          failure("Payload should have been invalid")
        }),
        invalid = (e => {
          // Should be one error
          e.length mustBeEqualTo(1)
        }))

    }
  }
}

import play.api.libs.functional.syntax._

case class SimpleObj(simpleValue1: String, simpleValue2: String)
object SimpleObj {
  val simpleReads = (
    (__ \ "simpleValue1").read[String] and
    (__ \ "simpleValue2").read[String])(SimpleObj.apply _) // read[String](minLength(0)) yields compiler error
  val simpleWrites = (
    (__ \ "simpleValue1").write[String] and
    (__ \ "simpleValue2").write[String])(unlift(SimpleObj.unapply))
  implicit val simpleFormat: Format[SimpleObj] = Format(simpleReads, simpleWrites)
} 

2 个答案:

答案 0 :(得分:6)

您可以在阅读中使用minLength:

import play.api.libs.json.Reads._

然后minLength应该可用,但是,请尝试这种格式:

implicit val simpleReads = (
  (__ \ "simpleValue1").read(minLength[String](1)) and
  (__ \ "simpleValue2").read(minLength[String](1))(SimpleObj.apply _)

答案 1 :(得分:2)

通过阅读Play2.1文档后,我能够添加一个客户读取验证器。如果从原始问题替换SimpleObj,则使用以下内容,测试用例将通过。不确定是否有更简单的方法可以做到这一点,但这绝对有效:

object SimpleObj {
  // defines a custom reads to be reused
  // a reads that verifies your value is not equal to a give value
  def notEqual[T](v: T)(implicit r: Reads[T]): Reads[T] = Reads.filterNot(ValidationError("validate.error.unexpected.value", v))(_ == v)

  implicit val simpleReads = (
    (__ \ "simpleValue1").read[String](notEqual("")) and
    (__ \ "simpleValue2").read[String](notEqual("")))(SimpleObj.apply _)

  val simpleWrites = (
    (__ \ "simpleValue1").write[String] and
    (__ \ "simpleValue2").write[String])(unlift(SimpleObj.unapply))
  implicit val simpleFormat: Format[SimpleObj] = Format(simpleReads, simpleWrites)
}