2

Play2.1 でオブジェクトにアンマーシャリングするときに JSON を検証しようとしています。私が定義した Format オブジェクトは、JSON にフィールドが存在しない場合にのみ検証しますが、フィールドが空でない文字列であることを検証したいと考えています。これは可能ですか?read() 呼び出しで minLength() 制約 (こちらを参照)を指定しようとしましたが、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)
} 
4

2 に答える 2

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)
} 
于 2013-03-15T15:46:41.247 に答える