2016-01-20 22 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我編輯了我的答案 –

相關問題