简体   繁体   English

使用Scala播放2.3,将JSON数组转换为Sequence

[英]Play 2.3 with Scala, converting JSON Array to Sequence

Welcome, 欢迎,

I really wanted to avoid this but i give up for now. 我真的想避免这种情况,但我现在就放弃了。 I am trying to traverse through json array and withdraw some elements and put them to sequence. 我试图遍历json数组并撤回一些元素并将它们排序。 I tried many options, tried all from play docs, many attempts and still i have the same error: null pointer exception when my method try to withdraw elements. 我尝试了很多选项,尝试了所有从播放文档,许多尝试,仍然我有相同的错误:当我的方法尝试撤回元素时空指针异常。 So my json example is: 所以我的json示例是:

[
  {
    "var1": "xx",
    "var2": "xxx",
    "var3": 111
  },
  {
    "var1": "yy",
    "var2": "yyy",
    "var3": 222 
  },
  {
    "var1": "zz",
    "var2": "zzz",
    "var3": 333    
  }
]

I defined many configurations of Reads, last one is like that but doesnt want to compile even ;/ 我定义了许多Reads的配置,最后一个是这样的,但是甚至不想编译; /

case class Vars1(vars: Seq[String])
val var1Reads: Reads[String] = (__ \ "var1").read[String]
implicit val vars1Reads: Reads[Vars1] = ((__).read[Seq[String]])(Vars1.apply _)

I want to create Sequence or List, this not important, from only var1 from each element of this array. 我想创建序列或列表,这不重要,仅来自此数组的每个元素的var1。 It can be pure sequence, or case class with sequence or other. 它可以是纯序列,也可以是带序列或其他的案例类。 Just how to iterate through json arrays? 如何迭代json数组? I tried many configurations, reading var1 is nonproblematic, but when i want read all vars 1 from each element of array then i have null pointer exception. 我尝试了很多配置,读取var1是没有问题的,但是当我想从数组的每个元素读取所有变量1时,我有空指针异常。 Please, anyone can point me in a good direction, give me a hint what i am doing wrong? 拜托,任何人都可以指出我的方向,给我一个暗示我做错了什么? Please don't blame I am newbie at programming, and i started to learn scala and play framework. 请不要责怪我是编程的新手,我开始学习scala和play框架。

Thank you for any help. 感谢您的任何帮助。

Update: 更新:

I have tried this one too: 我也试过这个:

implicit val vars1Reads = (__).read(Reads.list((__).read[String])).map( var => Vars(var))

but still i have the same error: 但我仍然有同样的错误:

[NoSuchElementException: JsError.get]

The easiest way of parsing this is to let Play parse the array body as a Seq[_] , that is, a sequence of objects. 解析这个的最简单方法是让Play将数组体解析为Seq[_] ,即一系列对象。

I would suggest that each item in your array should be represented by a case class, eg 我建议数组中的每个项都应该用case类表示,例如

case class Var1(var1: String)

This provides a useful type upon which to add validation of the input data from the JSON. 这提供了一种有用的类型,可以在其上添加来自JSON的输入数据的验证。

You can add an implicit Reads in an appropriate location, eg 您可以在适当的位置添加隐式Reads ,例如

object Var1 {
  implicit val var1Reads: Reads[Var1] = {
    ((__ \ "var1").read[String]).map(Var1.apply _)
  }
}

Note that the read/write macros have a limitation where they do not work in the documented way where the case class has a single field - see http://grokbase.com/t/gg/play-framework/131bx7pcyd/play2-1-scala-json-writing-a-reads-writes-for-a-single-field-case-class - This is why the map call is added. 请注意,读/写宏有一个限制,它不能以案例类具有单个字段的文档方式工作 - 请参阅http://grokbase.com/t/gg/play-framework/131bx7pcyd/play2-1 -scala-json-writing-a-reads-for-a-single-field-case-class - 这就是添加map调用的原因。 The macro should work as documented when there are 2 or more fields. 当有2个或更多字段时,宏应该按照记录的方式工作。

You may then use this to create a Seq[Var1], eg 然后,您可以使用它来创建Seq [Var1],例如

def test = Action(BodyParsers.parse.json) { request =>
  val result = request.body.validate[Seq[Var1]]
  ...
}

And the result (here I am just printing out the value of result.toString) is: 结果(这里我只是打印出result.toString的值)是:

$ curl --include --request POST --header "Content-type: application/json" --data '[{"var1": "3", "var2": "4"}, {"var1": "7"}]' http://localhost:9000/test
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 34

JsSuccess(List(Var1(3), Var1(7)),)

Update 更新

As mentioned in the comments below, you can simplify the Reads[Var1] implementation using a macro like this: 如下面的评论所述,您可以使用如下宏来简化Reads[Var1]实现:

implicit val var1Reads = Json.reads[Var1]

This will only do what you want, if the field is called var1 , ie 如果字段名为var1 ,即只能执行您想要的操作

case class Var1(var1: String)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM