2013-12-09 42 views
4

我在Scala中使用Playframework 2.2.1,并且正在编写一个REST API,用户可以在其中设置部分非结构化数据。基本上,用户将发布JSON看起来是这样的:Playframework:如何将JSON绑定到包含地图的案例类?

{ 
    "id": 1, 
    "name": "MyObject", 
    "properties": [ 
    "myFirstProperty": "Value 1", 
    "mySecondProperty": "Value 2" 
    ] 
} 

,我希望它绑定到一个案例类,看起来像:

case class Preference(id: Long, name: String, properties: Map[String, String]) 

我希望借此剧的形式API的优势为此,我可以免费获得一堆很好的验证选项,但是我一直无法找到一种简单的方法来实现这一点。理想的情况下(在我的脑海里至少),我将能够沿线的定义表单对象:

Form(
    mapping(
    "id" -> longNumber, 
    "name" -> nonEmptyText(min = 5), 
    "properties" -> map(nonEmptyText, nonEmptyText) 
)(Preference.apply)(Preference.unapply) 
) 

不幸的是,“地图(文本,文本)”是虚构的。有没有人使用表单API对此进行了类似的绑定?如果是这样,怎么样?如果没有,我很好奇你用什么来验证。这一切是手工完成的吗?

在此先感谢您的帮助!

+0

运气好吗? –

回答

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)

2

也许我误解了你的问题,但不是the reads macro做你想做的事?

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

implicit val preferenceReads = Json.reads[Preference] 

随着范围内隐,你可以使用asasOptvalidate你的JSON值转换为Preference(见the Play ScalaJson docs)。

+0

嗨@Aaron - 我编辑了这个问题,使其更加清晰,因为回想起来,我没有写得太好。我的问题是关于将JSON解析与Play的Forms API相结合,这使得基本验证(例如字符串长度)变得非常简单和优雅。 – Joe

相关问题