使用 play 将 JSON 值绑定到 Scala 类



我有一个相当复杂的表单,允许用户选择一些下拉值并在输入框中输入文本等。

该表单本质上是"高级搜索"类型的表单。

def search = Action(parse.json) { request =>
val sR = request.body.validate[SearchRequest]
sR.fold(
errors => {
BadRequest(Json.obj("status" -> "KO", "message" -> JsError.toJson(errors)))
},
searchRequest => {
Logger.debug(s"searchRequest is $searchRequest")
val sr = SearchResults(10)
Ok(Json.toJson(sr))
}
)
}

假设我有一个下拉列表,其中包含以下值:

IsGreaThan
IsLessThan
EqualTo

我的搜索请求如下所示:

case class SearchRequest(operator: String)

但我不希望用户可能发送错误数据,即"IsGreaterThan"、"IsLessThan"等以外的字符串。

当 JSON 绑定到搜索请求对象时,如何使其为强类型?

我认为您正在寻找的是枚举类型的Reads实例; 即:

声明一个特定的SearchOperator枚举:

object SearchOperator extends Enumeration {
type SearchOperator = Value
val IsGreaThan = Value("IsGreaThan")
val IsLessThan = Value("IsLessThan")
val EqualTo = Value("EqualTo")
}

SearchRequest案例类中使用它:

case class SearchRequest(lhs: Int, operator: SearchOperator, rhs:Int)

定义如何阅读它:

object SearchRequestJson {
implicit val soReads = Reads.enumNameReads(SearchOperator)
implicit val srReads = Json.reads[SearchRequest]
}

关键是 2.4 版添加到 Play 中的Reads.enumNameReads函数,并为您的情况保存了一堆样板。

现在,如果我提交非法值作为搜索请求的一部分:

{ "lhs": 42, "operator": "NotEqualTo", "rhs": 44 }

我得到一个:

JsError(
List(
(/operator, List(
ValidationError(
List(error.expected.enumstring),
WrappedArray()
)
))
)
)

最新更新