0

我正在尝试使用 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 左右一样可变。

谢谢你的帮助。

4

1 回答 1

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

使用此解决方案,您现在可以使用这些元组,但 IMO 代码的可读性会很差,因为使用_1,_2并且_3在此过程中。

所以这里有一种不同的方法(实际上更容易......)来解决这个理智编码的问题,这将简单地定义一个模拟你的原子数据的“案例类”

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请注意,由于在编译时使用了读取器的隐式创建,读者将始终关注数据表示的进一步变化,即's 字段。

现在,您将能够使用x,yplayer字段而不是_1,_2_3

于 2013-04-14T13:52:32.610 回答