我正在使用Play框架2.2.1与Scala,我正在编写一个REST API,用户可以在其中设置部分非结构化数据。基本上,用户将POST JSON看起来像这样:
{
"id": 1,
"name": "MyObject",
"properties": [
"myFirstProperty": "Value 1",
"mySecondProperty": "Value 2"
]
}
我希望它绑定到一个类似于:
的案例类case class Preference(id: Long, name: String, properties: Map[String, String])
我希望利用Play的表单API,因此我可以免费获得一堆很好的验证选项,但我还没有找到一种直接的方法来做到这一点。理想情况下(至少在我看来),我可以沿着以下几行定义一个Form对象:
Form(
mapping(
"id" -> longNumber,
"name" -> nonEmptyText(min = 5),
"properties" -> map(nonEmptyText, nonEmptyText)
)(Preference.apply)(Preference.unapply)
)
不幸的是,“地图(文字,文字)”是虚构的。有没有人使用表单API对此进行类似的绑定?如果是这样,怎么样?如果没有,我很好奇你用来验证的是什么。这一切都是手工完成的吗?
提前感谢您的帮助!
答案 0 :(得分:2)
也许我误解了你的问题,但是the reads
macro没有做你想做的事情?
import play.api.libs.json._
import play.api.libs.functional.syntax._
implicit val preferenceReads = Json.reads[Preference]
使用隐含的范围,您可以使用as
,asOpt
或validate
将您的JSON值转换为Preference
(请参阅the Play ScalaJson docs)
答案 1 :(得分:1)
据我所知,表单API和json支持并不意味着混合在一起。但这应该不是问题,因为您可以使用表单或json读取完成几乎所有验证。
import play.api.libs.json._
import play.api.libs.functional.syntax._
import play.api.libs.json.Reads._
import play.api.data.validation.ValidationError
val nonEmptyKeyValueMapReads =
filter[Map[String, String]](ValidationError("error.invalid"))(properties =>
properties.keys.find(_.size == 0).isEmpty && properties.values.find(_.size == 0).isEmpty)
val preferencesReads =
((__ \ 'id).read[Long] and
(__ \ 'name).read[String](minLength[String](5)) and
(__ \ 'properties).read[Map[String, String]](nonEmptyKeyValueMapReads))(Preferences)
有几种方法可以实现您的属性,这是其中之一。定义读取后,您可以使用它来验证数据,例如: myJson.validate(preferencesReads)