2016-01-20 143 views
0

我有以下函数接收JSON输入并使用"com.eclipsesource" %% "play-json-schema-validator" % "0.6.2"库对照JSON模式进行验证。当我收到无效的JSON时,一切都很好,我试着收集所有违规信息到List,随后返回该列表以及响应JSON。然而,我的列表编码为List()并且也有转义字符。我想有响应JSON这个样子的:如何从Scala中的响应JSON中删除List()和转义字符

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

取而代之的是:(这就是我现在越来越)

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

这里是为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) 
     } 
    ) 
    } 

    } 

更新1

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

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

回答

1

我通过修改这一行删除转义字符:

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

TO:

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

+1

请在下面的答案中查看我的评论。 另外,作为一种最佳实践,请尝试使用.asOpt [T]而不是.as [T]来优雅地处理输入JSON与您的预期不符的情况,Option是您的朋友:) –

+0

@emote_control:但是,当我更改.as [T] .asOpt [T]像'(msg(0).get).asOpt [String] :: violatesList'我得到这个错误:'表达式的列表[可序列化的] n不符合预期的类型列表[String]' – summerNight

+1

嗯,是的。你将得到一个'Option [String]'而不是'String',所以你不能将它添加到'List [String]'中。你需要处理它。好处是如果你的一个消息是null或者不是String,你就不会在运行时得到错误。缺点是你需要采取一个额外的步骤,以便将列表平整为只存在的字符串。 完成该操作的最快方法是声明'var violatesList:List [Option [String]]()',然后当您将其添加到JSON对象时使用Json.obj(“violations” - > violatesList.flatten) 。 –

1

你想要的是一个JSON数组,但致电名单上.toString(),你实际上是传递一个字符串。 Play有一个针对JSON数组的List的隐式序列化程序,所以您实际上只需少做一些你已经做过的事情 - 只需从violatesList.toString()中删除toString()部分即可。

此外,没有为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) 

关于你逃脱的报价,我想这是因为transactionIDmsgsJsString s,因此当您将它们转换为toString()时,将包含引号。只需删除toString无处不在,你会没事的。

+0

我删除'的ToString()',现在我得到以下错误: '[error] found:List [String] required:String [error] invalidError + =(“violations” - > violatesList) [error]^ ' – summerNight

+0

请让我知道您是否可以正确读取该错误,否则,我可以对实际问题进行编辑,以便错误代码格式正确。 – summerNight

+0

@summerNight我编辑了我的答案 –

相关问题