如何从Scala中的响应JSON中删除List()和转义字符

时间:2021-10-20 00:10:20

I have the following function that takes in a JSON input and validates it against a JSON-Schema using the "com.eclipsesource" %% "play-json-schema-validator" % "0.6.2" library. Everything works fine expect for when I get an invalid JSON, I try to collect all violations into a List and later return that list along with the response JSON. However my List is encoded with List() and also has escape characters. I want to have the response JSON look like this:

我有以下函数接受JSON输入并使用“com.eclipsesource”%%“play-json-schema-validator”%“0.6.2”库对JSON-Schema进行验证。当我得到一个无效的JSON时,一切都运行良好,我尝试将所有违规收集到List中,然后将该列表与响应JSON一起返回。但是我的List用List()编码,并且还有转义字符。我希望响应JSON看起来像这样:

{
  "transactionID": "123",
  "status": "error",
  "description": "Invalid Request Received",
  "violations": ["Wrong type. Expected integer, was string.", "Property action missing"]
}

Instead of this: (This is what I am getting right now)

而不是:(这就是我现在得到的)

{
  "transactionID": "\"123\"",
  "status": "error",
  "description": "Invalid Request Received",
  "violations": "List(\"Wrong type. Expected integer, was string.\", \"Property action missing\")"
}

And here's the actual function for JSON validation

这是JSON验证的实际功能

def validateRequest(json: JsValue): Result = {

    {
      val logger = LoggerFactory.getLogger("superman")
      val jsonSchema = Source.fromFile(play.api.Play.getFile("conf/schema.json")).getLines.mkString
      val transactionID = (json \ "transactionID").get
      val result: VA[JsValue] = SchemaValidator.validate(Json.fromJson[SchemaType](
        Json.parse(jsonSchema.stripMargin)).get, json)

      result.fold(
        invalid = { errors =>

          var violatesList = List[String]()
          var invalidError = Map("transactionID" -> transactionID.toString(), "status" -> "error", "description" -> "Invalid Request Received")
          for (msg <- (errors.toJson \\ "msgs"))
            violatesList = (msg(0).get).toString() :: violatesList
          invalidError += ("violations" -> (violatesList.toString()))
          //TODO: Make this parsable JSON list
          val errorResponse = Json.toJson(invalidError)
          logger.error("""Message="Invalid Request Received" for transactionID=""" + transactionID.toString() + "errorResponse:" + errorResponse)
          BadRequest(errorResponse)

        },

        valid = {
          post =>
            db.writeDocument(json)
            val successResponse = Json.obj("transactionID" -> transactionID.toString, "status" -> "OK", "message" -> ("Valid Request Received"))
            logger.info("""Message="Valid Request Received" for transactionID=""" + transactionID.toString() + "jsonResponse:" + successResponse)
            Ok(successResponse)
        }
      )
    }

  }

UPDATE 1

更新1

I get this after using Json.obj()

我使用Json.obj()后得到这个

{
  "transactionID": "\"123\"",
  "status": "error",
  "description": "Invalid Request Received",
  "violations": [
    "\"Wrong type. Expected integer, was string.\"",
    "\"Property action missing\""
  ]
}

2 个解决方案

#1


1  

What you want is a JSON array, but by calling .toString() on your list, you're actually passing a string. Play has an implicit serializer for Lists to JSON arrays, so you actually just have to do less then what you already did - you can just remove the toString() part from violatesList.toString().

你想要的是一个JSON数组,但是通过在列表中调用.toString(),你实际上是在传递一个字符串。 Play有一个LIST到JSON数组的隐式序列化程序,所以你实际上只需要做的就是你已经做过的事情 - 你可以从violatesList.toString()中删除toString()部分。

In addition, don't create a map for your JSON and then convert it to a JSON, you can use Json.obj with a very similar syntax instead:

此外,不要为您的JSON创建一个映射,然后将其转换为JSON,您可以使用具有非常相似语法的Json.obj:

val invalidError = Json.obj("transactionID" -> transactionID, "status" -> "error", "description" -> "Invalid Request Received")
for (msg <- (errors.toJson \\ "msgs"))
  violatesList = (msg(0).get) :: violatesList
val errorResponse = invalidError ++ Json.obj("violations" -> violatesList)

Regarding your escaped quotes, I suppose it's because transactionID and msgs are JsStrings, so when you convert them with toString() the quotes are included. Just remove the toString everywhere and you'll be fine.

关于你的转义引号,我想这是因为transactionID和msgs是JsStrings,所以当你用toString()转换它们时,会包含引号。只需在任何地方删除toString,你就可以了。

#2


1  

I got the escape characters removed by modifying this line:

我通过修改此行删除了转义字符:

violatesList = (msg(0).get).toString() :: violatesList

violatesList =(msg(0).get).toString():: violatesList

TO:

至:

violatesList = (msg(0).get).as[String] :: violatesList

violatesList =(msg(0).get).as [String] :: violatesList

#1


1  

What you want is a JSON array, but by calling .toString() on your list, you're actually passing a string. Play has an implicit serializer for Lists to JSON arrays, so you actually just have to do less then what you already did - you can just remove the toString() part from violatesList.toString().

你想要的是一个JSON数组,但是通过在列表中调用.toString(),你实际上是在传递一个字符串。 Play有一个LIST到JSON数组的隐式序列化程序,所以你实际上只需要做的就是你已经做过的事情 - 你可以从violatesList.toString()中删除toString()部分。

In addition, don't create a map for your JSON and then convert it to a JSON, you can use Json.obj with a very similar syntax instead:

此外,不要为您的JSON创建一个映射,然后将其转换为JSON,您可以使用具有非常相似语法的Json.obj:

val invalidError = Json.obj("transactionID" -> transactionID, "status" -> "error", "description" -> "Invalid Request Received")
for (msg <- (errors.toJson \\ "msgs"))
  violatesList = (msg(0).get) :: violatesList
val errorResponse = invalidError ++ Json.obj("violations" -> violatesList)

Regarding your escaped quotes, I suppose it's because transactionID and msgs are JsStrings, so when you convert them with toString() the quotes are included. Just remove the toString everywhere and you'll be fine.

关于你的转义引号,我想这是因为transactionID和msgs是JsStrings,所以当你用toString()转换它们时,会包含引号。只需在任何地方删除toString,你就可以了。

#2


1  

I got the escape characters removed by modifying this line:

我通过修改此行删除了转义字符:

violatesList = (msg(0).get).toString() :: violatesList

violatesList =(msg(0).get).toString():: violatesList

TO:

至:

violatesList = (msg(0).get).as[String] :: violatesList

violatesList =(msg(0).get).as [String] :: violatesList