Java 如何解析邮递员集合?
目标: 我试图解析postman_echo集合json,并将结果持久化到磁盘上的一个新json副本中,生成与原始文件相同的文件 我更喜欢该语言中的内置数据结构,但使用json库也应该不错。不确定Antlr4是否是更好的方法 后续问题 在post请求主体中是否允许任何有效的嵌套json 更新:Java 如何解析邮递员集合?,java,json,scala,Java,Json,Scala,目标: 我试图解析postman_echo集合json,并将结果持久化到磁盘上的一个新json副本中,生成与原始文件相同的文件 我更喜欢该语言中的内置数据结构,但使用json库也应该不错。不确定Antlr4是否是更好的方法 后续问题 在post请求主体中是否允许任何有效的嵌套json 更新: 最后,我们提出了一个令人满意的解决方案。我不确定我是否理解您的问题,但如果您试图迭代json字符串,您可以尝试以下方法: import play.api.libs.json.{JsObject, JsV
最后,我们提出了一个令人满意的解决方案。我不确定我是否理解您的问题,但如果您试图迭代json字符串,您可以尝试以下方法:
import play.api.libs.json.{JsObject, JsValue, Json}
import scala.util.{Failure, Success, Try}
object JsonParser extends App {
val postman_coolections = "./resources/scala_input.json"
val jsonifiedString = scala.io.Source.fromFile(postman_coolections).mkString
val json: JsValue = Try(Json.parse(jsonifiedString)) match {
case Success(js) => js
case Failure(ex) => throw new Exception("Couldn't parse json", ex)
}
json.asInstanceOf[JsObject].fields.foreach{
case (key: String, value: JsValue)=>
println(s"Key:$key value:${value.toString}")
writeFile(s"$key.json", Json.prettyPrint(value))
}
//writing the whole postman input as a single file
writeFile("postmanInputFormatted.json", Json.prettyPrint(json))
writeFile("postmanInput.json", Json.stringify(json))
// To access individual property one option is to use this approach
val lookedValue = json \ "postData" \ "params" \ 1 \ "hello" \ "test"
lookedValue match {
case JsDefined(value) => println(s"Test value is $value")
case JsUndefined() => println("Didn't find test value")
}
// or
val lookedValueAlt = (json \ "postData" \ "params" \ 1 \ "hello" \ "test").getOrElse(throw SomeException)
case class Request(
method: String,
header: Seq[HeaderItem], // header: []
url: Option[Url] = None,
description: String = ""
)
object Request {
implicit val format: Format[Request] = Json.using[Json.WithDefaultValues].format
case class HeaderItem(key: String, value: String)
object HeaderItem {
implicit val format: Format[HeaderItem] = Json.format
}
我不确定我是否理解您的问题,但如果您试图迭代json字符串,您可能会尝试以下方法:
import play.api.libs.json.{JsObject, JsValue, Json}
import scala.util.{Failure, Success, Try}
object JsonParser extends App {
val postman_coolections = "./resources/scala_input.json"
val jsonifiedString = scala.io.Source.fromFile(postman_coolections).mkString
val json: JsValue = Try(Json.parse(jsonifiedString)) match {
case Success(js) => js
case Failure(ex) => throw new Exception("Couldn't parse json", ex)
}
json.asInstanceOf[JsObject].fields.foreach{
case (key: String, value: JsValue)=>
println(s"Key:$key value:${value.toString}")
writeFile(s"$key.json", Json.prettyPrint(value))
}
//writing the whole postman input as a single file
writeFile("postmanInputFormatted.json", Json.prettyPrint(json))
writeFile("postmanInput.json", Json.stringify(json))
// To access individual property one option is to use this approach
val lookedValue = json \ "postData" \ "params" \ 1 \ "hello" \ "test"
lookedValue match {
case JsDefined(value) => println(s"Test value is $value")
case JsUndefined() => println("Didn't find test value")
}
// or
val lookedValueAlt = (json \ "postData" \ "params" \ 1 \ "hello" \ "test").getOrElse(throw SomeException)
case class Request(
method: String,
header: Seq[HeaderItem], // header: []
url: Option[Url] = None,
description: String = ""
)
object Request {
implicit val format: Format[Request] = Json.using[Json.WithDefaultValues].format
case class HeaderItem(key: String, value: String)
object HeaderItem {
implicit val format: Format[HeaderItem] = Json.format
}
zoran提到的另一种方法是,如果使用Play JSON时结构不太动态,则创建一个case类。这将使比较结果更容易
case class MyObject(
queryString: List[KeyValue],
method: String,
url: String,
httpVersion: String
) ... and so on
object MyObject {
implicit val format: Format[MyObject] = Json.format
}
case class KeyValue(name: String, value: String)
object KeyValue {
implicit val format: Format[KeyValue] = Json.format
}
然后,您只需执行以下操作:
object JsonParser extends App {
val postman_collections = "./scala_input.json"
val jsonifiedString = scala.io.Source.fromFile(postman_collections).mkString
val myJsonData = Try(Json.parse(jsonifiedString)).map(_.as[MyObject])
myJsonData match {
case Success(myValue) => // compare your case class here
case Failure(err) => println("none")
}
}
zoran提到的另一种方法是,如果使用Play JSON时结构不太动态,则创建一个case类。这将使比较结果更容易
case class MyObject(
queryString: List[KeyValue],
method: String,
url: String,
httpVersion: String
) ... and so on
object MyObject {
implicit val format: Format[MyObject] = Json.format
}
case class KeyValue(name: String, value: String)
object KeyValue {
implicit val format: Format[KeyValue] = Json.format
}
然后,您只需执行以下操作:
object JsonParser extends App {
val postman_collections = "./scala_input.json"
val jsonifiedString = scala.io.Source.fromFile(postman_collections).mkString
val myJsonData = Try(Json.parse(jsonifiedString)).map(_.as[MyObject])
myJsonData match {
case Success(myValue) => // compare your case class here
case Failure(err) => println("none")
}
}
解析器中存在多个问题,其中大多数问题是您试图使用默认解析器将Json对象作为字符串处理。例如,在请求中,您将头作为Seq[String]处理,而实际上它是键、值对的Seq。对于这种特殊情况,您应该将其更改为以下内容:
import play.api.libs.json.{JsObject, JsValue, Json}
import scala.util.{Failure, Success, Try}
object JsonParser extends App {
val postman_coolections = "./resources/scala_input.json"
val jsonifiedString = scala.io.Source.fromFile(postman_coolections).mkString
val json: JsValue = Try(Json.parse(jsonifiedString)) match {
case Success(js) => js
case Failure(ex) => throw new Exception("Couldn't parse json", ex)
}
json.asInstanceOf[JsObject].fields.foreach{
case (key: String, value: JsValue)=>
println(s"Key:$key value:${value.toString}")
writeFile(s"$key.json", Json.prettyPrint(value))
}
//writing the whole postman input as a single file
writeFile("postmanInputFormatted.json", Json.prettyPrint(json))
writeFile("postmanInput.json", Json.stringify(json))
// To access individual property one option is to use this approach
val lookedValue = json \ "postData" \ "params" \ 1 \ "hello" \ "test"
lookedValue match {
case JsDefined(value) => println(s"Test value is $value")
case JsUndefined() => println("Didn't find test value")
}
// or
val lookedValueAlt = (json \ "postData" \ "params" \ 1 \ "hello" \ "test").getOrElse(throw SomeException)
case class Request(
method: String,
header: Seq[HeaderItem], // header: []
url: Option[Url] = None,
description: String = ""
)
object Request {
implicit val format: Format[Request] = Json.using[Json.WithDefaultValues].format
case class HeaderItem(key: String, value: String)
object HeaderItem {
implicit val format: Format[HeaderItem] = Json.format
}
如果需要,可以将标题转换为Seq[String],但必须为此编写自定义读取。
在上述情况下,还存在缺少描述的情况,因此您希望使用默认值处理该情况。
在其他一些地方,你也有这样的问题需要处理,例如响应
我注意到的另一个问题是如何从Json字符串处理类型属性。Type是保留关键字,您可以通过将其包装在``中来处理它,例如
case class Script(
`type`: String,
exec: Seq[String]
)
解析器中存在多个问题,其中大多数问题是您试图使用默认解析器将Json对象作为字符串处理。例如,在请求中,您将头作为Seq[String]处理,而实际上它是键、值对的Seq。对于这种特殊情况,您应该将其更改为以下内容:
import play.api.libs.json.{JsObject, JsValue, Json}
import scala.util.{Failure, Success, Try}
object JsonParser extends App {
val postman_coolections = "./resources/scala_input.json"
val jsonifiedString = scala.io.Source.fromFile(postman_coolections).mkString
val json: JsValue = Try(Json.parse(jsonifiedString)) match {
case Success(js) => js
case Failure(ex) => throw new Exception("Couldn't parse json", ex)
}
json.asInstanceOf[JsObject].fields.foreach{
case (key: String, value: JsValue)=>
println(s"Key:$key value:${value.toString}")
writeFile(s"$key.json", Json.prettyPrint(value))
}
//writing the whole postman input as a single file
writeFile("postmanInputFormatted.json", Json.prettyPrint(json))
writeFile("postmanInput.json", Json.stringify(json))
// To access individual property one option is to use this approach
val lookedValue = json \ "postData" \ "params" \ 1 \ "hello" \ "test"
lookedValue match {
case JsDefined(value) => println(s"Test value is $value")
case JsUndefined() => println("Didn't find test value")
}
// or
val lookedValueAlt = (json \ "postData" \ "params" \ 1 \ "hello" \ "test").getOrElse(throw SomeException)
case class Request(
method: String,
header: Seq[HeaderItem], // header: []
url: Option[Url] = None,
description: String = ""
)
object Request {
implicit val format: Format[Request] = Json.using[Json.WithDefaultValues].format
case class HeaderItem(key: String, value: String)
object HeaderItem {
implicit val format: Format[HeaderItem] = Json.format
}
如果需要,可以将标题转换为Seq[String],但必须为此编写自定义读取。
在上述情况下,还存在缺少描述的情况,因此您希望使用默认值处理该情况。
在其他一些地方,你也有这样的问题需要处理,例如响应
我注意到的另一个问题是如何从Json字符串处理类型属性。Type是保留关键字,您可以通过将其包装在``中来处理它,例如
case class Script(
`type`: String,
exec: Seq[String]
)
谢谢分享。但它想做什么呢?case类和object同时存在吗?另外,最棘手的部分是。。。等等属性params:params:[{name:foo,value:bar},{hello:{test:world},value:bar}]中有一个嵌套的json结构。这种方法可以通过键访问,但无法使用所需输出写入磁盘问题的github链接中发布了令人满意的解决方案。感谢您的分享。但它想做什么呢?case类和object同时存在吗?另外,最棘手的部分是。。。等等属性params:params:[{name:foo,value:bar},{hello:{test:world},value:bar}]中有一个嵌套的json结构。这种方法可以通过键访问,但是无法用所需的输出写入磁盘问题的github链接中发布了一个令人满意的解决方案。从您的评论中不太清楚您想要实现什么。根据我对你问题的理解,我更新了我的答案。如果将json转换为字符串,则无法迭代json,因此必须迭代JsValue并将其转换为字符串,以便通过使用json.prettyPrint或json.stringify将其保存到文件中。如果需要,prettyPrint将保持Json格式。希望这有帮助。我已经更新了我的答案,以涵盖您的第一个问题:如何访问单个元素(如果存在)。然而,我从Play Json中发现的JsValue类型会给出不希望的磁盘输出的问题不是很清楚。你能澄清一下你期望得到什么以及你的实际产出是什么吗?我得到了输入文档中给出的正确输出。一个令人满意的解决方案发布在问题的上面的github链接中。从您的评论中不太清楚您想要实现什么。根据我对你问题的理解,我更新了我的答案。如果将json转换为字符串,则无法迭代json,因此必须迭代JsValue,并将其转换为字符串,以便将其持久化为字符串
使用Json.prettyPrint或Json.stringify创建文件。如果需要,prettyPrint将保持Json格式。希望这有帮助。我已经更新了我的答案,以涵盖您的第一个问题:如何访问单个元素(如果存在)。然而,我从Play Json中发现的JsValue类型会给出不希望的磁盘输出的问题不是很清楚。你能澄清一下你期望得到什么以及你的实际产出是什么吗?我得到了输入文档中给出的正确输出。问题中的github链接中发布了一个令人满意的解决方案。因此,原来案例类生成器没有为此生成好的案例类?尽管如此,在做了这个更改之后,仍然不足以解析整个postman JSONY。正如我在回答中所写的,这不是代码中唯一的问题。在类Item1中,您没有正确解析响应。您必须应用类似于我在这个示例中对header所做的操作。响应不能是响应:Seq[String]。它应该类似于response:response,然后您将拥有case类Responsename:String,originalRequest:originalRequest,status:String,code:Int。。。等等所以,您需要提供所有这些的正确映射。如果您只是注释掉case class Item1中的line response:Seq[String],您将看到解析器工作正常,这意味着唯一的突出问题是response属性。我建议您获取响应的全部内容,并为其生成case类。显然,您使用的案例类生成器并没有正确地生成它。所以,事实证明,案例类生成器并没有为此生成好的案例类?尽管如此,在做了这个更改之后,仍然不足以解析整个postman JSONY。正如我在回答中所写的,这不是代码中唯一的问题。在类Item1中,您没有正确解析响应。您必须应用类似于我在这个示例中对header所做的操作。响应不能是响应:Seq[String]。它应该类似于response:response,然后您将拥有case类Responsename:String,originalRequest:originalRequest,status:String,code:Int。。。等等所以,您需要提供所有这些的正确映射。如果您只是注释掉case class Item1中的line response:Seq[String],您将看到解析器工作正常,这意味着唯一的突出问题是response属性。我建议您获取响应的全部内容,并为其生成case类。显然,您使用的案例类生成器没有正确地生成它。