如何解析包含在 Scala 中始终更改名称的字段的 json?
How to parse a json containing a field that always has a changed name in Scala?
我目前有一个来自 API 的非常大的 json 响应,我想 json 解析它。我的应用程序正在使用 play 和 Scala。
为此,我使用了 case classes,稍后我将使用隐式解析它。但是现在我已经意识到在我的一个案例中 classes 我有一个总是在更改名称的字段。如何解析它?
例如,我有 json 响应的这一部分:
"customerInfo": {
"number": "123456XXXXXX7891",
"email": "randomname@gmail.com",
"billingFirstName": "Random",
"billingLastName": "Name"
},
我将用这个解析:
case class CustomerInfo (
number: String,
email: String,
billingFirstName: String,
billingLastName: String
)
但是我在 json 中有一个变化的字段,看起来像这样:
"Check": {
"5c123456":
"{random numbers inside here}"
}
这个字段“5c123456”总是在变化,永远不会相同"name"。
我将如何解析它?如果没有,我是否可以忽略这种情况 class 检查并仍然解析 json 的其余部分?非常感谢任何帮助。
已编辑以添加额外信息
澄清一下,我想做的是能够像这样解析它:
val result = Json.fromJson[RootInterface](res.json).get
这是整个响应的示例:
val response = : """{
"per_page": 50,
"current_page": 1,
"next_page_url": "http:\/\/testapi.com\/api\/v3\/testing\/list?page=2",
"prev_page_url": null,
"from": 1,
"to": 50,
"data": [
{
"customerInfo": {
"number": "1234",
"email": "felix@ytesting.com",
"billingFirstName": "Felix",
"billingLastName": "Testing"
},
"updated_at": "2018-12-13 16:10:08",
"created_at": "2018-12-13 14:06:54",
"fx": {
"merchant": {
"originalAmount": 1234,
"originalCurrency": "EUR",
"convertedAmount": 1234,
"convertedCurrency": "EUR"
}
},
"raw": {
"Check": {
"5c1283dad": "{\"id\":\"1234-5678-4da1-a3ea-5aa0c2b8a3f3\",\"status\":\"TEST\",\"risk_score\":0,\"descriptions\":{},\"testRuleId\":null,\"triggeredExceptionRuleId\":null,\"reason\":null}"
}
},
"acquirer": {
"type": "TESTCARD"
},
"transaction": {
"merchant": {
"referenceNo": "12345",
"status": "TEST",
"operation": "TEST",
"type": "AUTH",
"message": "TESTING",
"customData": "1234",
"created_at": "2018-12-12 15:10:07",
"transactionId": "12345"
}
},
"refundable": false,
"merchant": {
"id": 1234,
"name": "Felix Testing",
"allowPartialRefund": false,
"allowPartialCapture": false
},
"ipn": {
"sent": true,
"merchant": {
"transactionId": "123456789",
"referenceNo": "1234",
"amount": 1234,
"currency": "EUR",
"date": 1544717407,
"code": "42",
"message": "TESTING",
"operation": "TEST",
"type": "AUTH",
"status": "DECLINED",
"customData": "12345",
"paymentType": "TESTCARD",
"authTransactionId": "123456",
"descriptor": "Felix Testing",
"token": "123456789token",
"convertedAmount": 1234,
"convertedCurrency": "EUR",
"ipnType": "TESTIP",
"_queueReadCountKey": 1
}
}
}
]
}"""
我有这些案例分类:
case class Acquirer(
`type`: String
)
case class CustomerInfo (
number: String,
email: String,
billingFirstName: String,
billingLastName: String
)
case class Data (
customerInfo: CustomerInfo,
updated_at: String,
created_at: String,
fx: Fx,
raw: Option[Raw],
acquirer: Acquirer,
transaction: transaction,
refundable: Boolean,
merchant: Merchant2,
ipn: Ipn
)
case class transaction(
merchant : Merchant1
)
case class Fx (
merchant: Merchant
)
case class Ipn (
sent: Boolean,
merchant: Merchant3
)
case class Merchant (
originalAmount: Int,
originalCurrency: String,
convertedAmount: Int,
convertedCurrency: String
)
case class Merchant1 (
referenceNo: String,
status: String,
operation: String,
`type`: String,
message: String,
customData: String,
created_at: String,
transactionId: String
)
case class Merchant2 (
id: Int,
name: String,
allowPartialRefund: Boolean,
allowPartialCapture: Boolean
)
case class Merchant3 (
transactionId: String,
referenceNo: String,
amount: Int,
currency: String,
date: Int,
code: String,
message: String,
operation: String,
`type`: String,
status: String,
customData: String,
paymentType: String,
authTransactionId: String,
descriptor: String,
token: String,
convertedAmount: Int,
convertedCurrency: String,
ipnType: String,
_queueReadCountKey: Int
)
)
case class Raw(Check: Map[String, String])
case class RootInterface (
per_page: Int,
current_page: Int,
next_page_url: String,
prev_page_url: String,
from: Int,
to: Int,
data: List[Data]
)
这些隐式:
implicit val RootInterface: Format[RootInterface] = Json.format[RootInterface]
implicit val Data: Format[Data] = Json.format[Data]
implicit val CustomerInfo: Format[CustomerInfo] = Json.format[CustomerInfo]
implicit val Fx: Format[Fx] = Json.format[Fx]
implicit val Transaction: Format[transaction] = Json.format[transaction]
implicit val Acquirer: Format[Acquirer] = Json.format[Acquirer]
implicit val Merchant: Format[Merchant] = Json.format[Merchant]
implicit val Merchant1: Format[Merchant1] = Json.format[Merchant1]
implicit val Merchant2: Format[Merchant2] = Json.format[Merchant2]
implicit val Merchant3: Format[Merchant3] = Json.format[Merchant3]
implicit val Ipn: Format[Ipn] = Json.format[Ipn]
implicit val jsonFormat: Format[Raw] = Json.format[Raw]
如评论中所述,动态字段使用 Map
处理。这是一个例子:
像这样定义 case-class
:
import play.api.libs.json._
case class MyObject(Check: Map[String, String])
定义隐式格式:
object MyObject {
implicit val jsonFormat: OFormat[MyObject] = Json.format[MyObject]
}
使用 validate
从 Json
创建 case-class
val json = Json.parse("""{ "Check": {
"5c123456":
"123239"
}}""")
json.validate[MyObject] // > JsSuccess(MyObject(Map(5c123456 -> 123239)),)
这是要检查的 Scalafiddle:Scalafiddle
这里是相应的文档:JSON-automated-mapping
我目前有一个来自 API 的非常大的 json 响应,我想 json 解析它。我的应用程序正在使用 play 和 Scala。 为此,我使用了 case classes,稍后我将使用隐式解析它。但是现在我已经意识到在我的一个案例中 classes 我有一个总是在更改名称的字段。如何解析它?
例如,我有 json 响应的这一部分:
"customerInfo": {
"number": "123456XXXXXX7891",
"email": "randomname@gmail.com",
"billingFirstName": "Random",
"billingLastName": "Name"
},
我将用这个解析:
case class CustomerInfo (
number: String,
email: String,
billingFirstName: String,
billingLastName: String
)
但是我在 json 中有一个变化的字段,看起来像这样:
"Check": {
"5c123456":
"{random numbers inside here}"
}
这个字段“5c123456”总是在变化,永远不会相同"name"。 我将如何解析它?如果没有,我是否可以忽略这种情况 class 检查并仍然解析 json 的其余部分?非常感谢任何帮助。
已编辑以添加额外信息
澄清一下,我想做的是能够像这样解析它:
val result = Json.fromJson[RootInterface](res.json).get
这是整个响应的示例:
val response = : """{
"per_page": 50,
"current_page": 1,
"next_page_url": "http:\/\/testapi.com\/api\/v3\/testing\/list?page=2",
"prev_page_url": null,
"from": 1,
"to": 50,
"data": [
{
"customerInfo": {
"number": "1234",
"email": "felix@ytesting.com",
"billingFirstName": "Felix",
"billingLastName": "Testing"
},
"updated_at": "2018-12-13 16:10:08",
"created_at": "2018-12-13 14:06:54",
"fx": {
"merchant": {
"originalAmount": 1234,
"originalCurrency": "EUR",
"convertedAmount": 1234,
"convertedCurrency": "EUR"
}
},
"raw": {
"Check": {
"5c1283dad": "{\"id\":\"1234-5678-4da1-a3ea-5aa0c2b8a3f3\",\"status\":\"TEST\",\"risk_score\":0,\"descriptions\":{},\"testRuleId\":null,\"triggeredExceptionRuleId\":null,\"reason\":null}"
}
},
"acquirer": {
"type": "TESTCARD"
},
"transaction": {
"merchant": {
"referenceNo": "12345",
"status": "TEST",
"operation": "TEST",
"type": "AUTH",
"message": "TESTING",
"customData": "1234",
"created_at": "2018-12-12 15:10:07",
"transactionId": "12345"
}
},
"refundable": false,
"merchant": {
"id": 1234,
"name": "Felix Testing",
"allowPartialRefund": false,
"allowPartialCapture": false
},
"ipn": {
"sent": true,
"merchant": {
"transactionId": "123456789",
"referenceNo": "1234",
"amount": 1234,
"currency": "EUR",
"date": 1544717407,
"code": "42",
"message": "TESTING",
"operation": "TEST",
"type": "AUTH",
"status": "DECLINED",
"customData": "12345",
"paymentType": "TESTCARD",
"authTransactionId": "123456",
"descriptor": "Felix Testing",
"token": "123456789token",
"convertedAmount": 1234,
"convertedCurrency": "EUR",
"ipnType": "TESTIP",
"_queueReadCountKey": 1
}
}
}
]
}"""
我有这些案例分类:
case class Acquirer(
`type`: String
)
case class CustomerInfo (
number: String,
email: String,
billingFirstName: String,
billingLastName: String
)
case class Data (
customerInfo: CustomerInfo,
updated_at: String,
created_at: String,
fx: Fx,
raw: Option[Raw],
acquirer: Acquirer,
transaction: transaction,
refundable: Boolean,
merchant: Merchant2,
ipn: Ipn
)
case class transaction(
merchant : Merchant1
)
case class Fx (
merchant: Merchant
)
case class Ipn (
sent: Boolean,
merchant: Merchant3
)
case class Merchant (
originalAmount: Int,
originalCurrency: String,
convertedAmount: Int,
convertedCurrency: String
)
case class Merchant1 (
referenceNo: String,
status: String,
operation: String,
`type`: String,
message: String,
customData: String,
created_at: String,
transactionId: String
)
case class Merchant2 (
id: Int,
name: String,
allowPartialRefund: Boolean,
allowPartialCapture: Boolean
)
case class Merchant3 (
transactionId: String,
referenceNo: String,
amount: Int,
currency: String,
date: Int,
code: String,
message: String,
operation: String,
`type`: String,
status: String,
customData: String,
paymentType: String,
authTransactionId: String,
descriptor: String,
token: String,
convertedAmount: Int,
convertedCurrency: String,
ipnType: String,
_queueReadCountKey: Int
)
)
case class Raw(Check: Map[String, String])
case class RootInterface (
per_page: Int,
current_page: Int,
next_page_url: String,
prev_page_url: String,
from: Int,
to: Int,
data: List[Data]
)
这些隐式:
implicit val RootInterface: Format[RootInterface] = Json.format[RootInterface]
implicit val Data: Format[Data] = Json.format[Data]
implicit val CustomerInfo: Format[CustomerInfo] = Json.format[CustomerInfo]
implicit val Fx: Format[Fx] = Json.format[Fx]
implicit val Transaction: Format[transaction] = Json.format[transaction]
implicit val Acquirer: Format[Acquirer] = Json.format[Acquirer]
implicit val Merchant: Format[Merchant] = Json.format[Merchant]
implicit val Merchant1: Format[Merchant1] = Json.format[Merchant1]
implicit val Merchant2: Format[Merchant2] = Json.format[Merchant2]
implicit val Merchant3: Format[Merchant3] = Json.format[Merchant3]
implicit val Ipn: Format[Ipn] = Json.format[Ipn]
implicit val jsonFormat: Format[Raw] = Json.format[Raw]
如评论中所述,动态字段使用 Map
处理。这是一个例子:
像这样定义 case-class
:
import play.api.libs.json._
case class MyObject(Check: Map[String, String])
定义隐式格式:
object MyObject {
implicit val jsonFormat: OFormat[MyObject] = Json.format[MyObject]
}
使用 validate
从 Json
case-class
val json = Json.parse("""{ "Check": {
"5c123456":
"123239"
}}""")
json.validate[MyObject] // > JsSuccess(MyObject(Map(5c123456 -> 123239)),)
这是要检查的 Scalafiddle:Scalafiddle
这里是相应的文档:JSON-automated-mapping