1

Play 2.1.0 を使用しています。POST リクエストを受け入れ、リクエスト本文にブール値が必要なアクションを作成しようとしています。今起こっていることは、param を指定しなくても、Action が偽の値を取得することです。テストコード:

// /post/boolean/single routes to this method
def postTestBooleanSingle = Action { implicit request =>
    val form = Form("flag" -> boolean)
    form.bindFromRequest.fold(
        formWithErrors =>
            BadRequest(formWithErrors.errors map (fe => fe.key + ": " + fe.message) mkString ", "),
        flag => Ok(f"got $flag%b")
    )
}

// /post/num/single routes to this method
def postTestNumSingle = Action { implicit request =>
    val form = Form("num" -> number)
    form.bindFromRequest.fold(
        formWithErrors => 
            BadRequest(formWithErrors.errors map (fe => fe.key + ": " + fe.message) mkString ", "),
        num => Ok(f"got $num%d")
    )
}

$ curl -XPOST -d "num=42" http://localhost:9000/post/num/single
got 42
$ curl -XPOST http://localhost:9000/post/num/single
num: error.required // didn't provide num so i get an error
$ curl -XPOST -d "flag=true" http://localhost:9000/post/boolean/single
got true
$ curl -XPOST http://localhost:9000/post/boolean/single
got false // ???

ブール値パラメーターを要求するにはどうすればよいですか?

4

1 に答える 1

4

理由はわかりませんが、Boolean 型の Form マッピングは、パラメーターがない場合にデフォルトで false に設定されているようです。

Play ソースの Format.scala のスニペットは次のとおりです。

/**
 * Default formatter for the `Boolean` type.
 */
implicit def booleanFormat: Formatter[Boolean] = new Formatter[Boolean] {

  override val format = Some(("format.boolean", Nil))

  def bind(key: String, data: Map[String, String]) = {
    Right(data.get(key).getOrElse("false")).right.flatMap {
      case "true" => Right(true)
      case "false" => Right(false)
      case _ => Left(Seq(FormError(key, "error.boolean", Nil)))
    }
  }

  def unbind(key: String, value: Boolean) = Map(key -> value.toString)
}

ここで重要な部分はdata.get(key).getOrElse("false"). 入力がない場合、ブール値はデフォルトで false になります。カスタム フォーマッタを作成し、それを使用してブール値のカスタム バインディングを定義する必要があります。

これらをコード ベースの適切な場所に配置するのはあなたに任せますが、パズルのピースは次のようになります。

// This is the custom formatter to support your custom mapping.
import play.api.data.format.Formatter
implicit def requiredBooleanFormatter: Formatter[Boolean] = new Formatter[Boolean] {

  override val format = Some(("format.boolean", Nil))

  def bind(key: String, data: Map[String, String]) = {
    Right(data.get(key).getOrElse("")).right.flatMap {
      case "true" => Right(true)
      case "false" => Right(false)
      case _ => Left(Seq(FormError(key, "error.boolean", Nil)))
    }
  }

  def unbind(key: String, value: Boolean) = Map(key -> value.toString)
}

// This is your custom mapping to be used in the form
import play.api.data.Forms
val requiredBoolean: Mapping[Boolean] = Forms.of[Boolean](requiredBooleanFormatter)

.getOrElse("false")からへの変化に注意してください.getOrElse("")。コードはほとんど同じですが、空の値をエラー キャッチャーに値を持たせる代わりにプッシュしていfalseます。requiredBooleanFormatter(注:この例ではわかりやすくするために明示的に指定していますがrequiredBooleanFormatter、暗黙的で範囲内であるため、指定する必要はありません。)

requiredBooleanこれで、フォームの代わりに使用booleanして、リクエストでパラメーターが明示的に設定されていることを要求できるようになりました。

于 2013-05-09T21:56:36.917 に答える