我正在尝试使用JSON请求将数据从客户端发送到服务器。 JSON请求的主体如下所示:
[
[
{"x":"0","y":"0","player":0},
{"x":"0","y":"1","player":0},
{"x":"0","y":"2","player":1}
],
[
{"x":"1","y":"0","player":0},
{"x":"1","y":"1","player":2},
{"x":"1","y":"2","player":0}
],
[
{"x":"2","y":"0","player":0},
{"x":"2","y":"1","player":1},
{"x":"2","y":"2","player":2}
]
]
在服务器端,我想将Play 2框架的数据转换为Scala 2D列表,如下所示:
List(
List(0,0,1),
List(0,2,0),
List(0,1,2)
)
这是3x3,但它可以变化,如50x50左右。
感谢您的帮助。
答案 0 :(得分:1)
它可能不完整(不知道你是否想要对方形矩阵约束进行建模)但这样的事情可能是一个好的开始:
首先,这是控制器(和模型)部件可以定义的内容
import play.api.libs.json.Json._
import play.api.libs.json._
type PlayerT = (String, String, Int)
implicit val playerTripleReads:Reads[PlayerT] = (
(__ \ "x").read[String] and
(__ \ "y").read[String] and
(__ \ "player").read[Int]
tupled
)
def getJson = Action(parse.json) { request =>
request.body.validate[List[List[PlayerT]]].map{
case xs => Ok(xs.mkString("\n"))
}.recoverTotal{
e => BadRequest("Detected error:"+ JsError.toFlatJson(e))
}
}
在此版本中,您将获得一个列表,其中包含(String, String, Int)
格式的已验证元组,该格式已使用PlayerT
类型别名以节省一些输入内容。
正如您所看到的,读者是通过组合(使用and
组合子)三个基本块“手动”创建的,并且使用tupled
运算符将结果展平。
使用此解决方案,您现在可以使用这些元组,但由于_1
,_2
和_3
的使用,IMO代码的可读性会受到影响一路上。
所以这里有一种不同的方法(实际上更容易......)解决了这个理智的编码问题,这将简单地定义一个用于模拟原子数据的案例类
case class Player(x:String, y:String, player:Int)
implicit val playerReads = Json.reads[Player]
def getJson = Action(parse.json) { request =>
request.body.validate[List[List[Player]]].map{
case xs => Ok(xs.mkString("\n"))
}.recoverTotal{
e => BadRequest("Detected error:"+ JsError.toFlatJson(e))
}
}
请注意,由于在编译时使用了隐式的读者创建,读者将始终关注数据表示中的进一步更改,即case class
的字段。
现在,您将能够使用x
,y
和player
字段,而不是_1
,_2
和_3
。