编辑 - 已解决:发布的结果是我们的日志记录代码以及 json.org 如何处理 Javascript null 和 Javascript undefined 之间的区别的组合。我们的日志代码没有在对象中打印空值,所以虽然我看到的 json 对象没有“发票”字段,但实际输入有一个空的“发票”字段。JSONObject 的 .has() 方法报告说有一个“发票”字段,但是当我尝试访问它时,它的值为 null,因此无法访问它。将 .has() 检查替换为 .isNull() 检查(同时考虑缺失字段和空值)解决了问题。
在我的 Google App Engine 应用程序中,我们以 json 的形式解析 webhook 数据,并根据 json 对象中某个键的存在情况走不同的代码路径 - 如果 $.data.object.invoice 存在,我们会做一些工作,否则我们没有。但是,在生产中运行时,这种检测似乎被破坏了。我做一个简单的
jsonObject.getJSONObject("data").getJSONObject("object").has("invoice")
检查发票密钥,有时即使发票密钥不存在也会返回true。我遇到了这个错误,因为我们确实使用了存在的发票值,并且我得到 JSONExceptions 试图访问它,即使它受到 has() 检查的保护。我添加了以下日志记录以确保我做的一切都是正确的:
boolean isAutomaticCharge = jsonObject.getJSONObject("data").getJSONObject("object").has("invoice");
boolean doesGettingStringWork;
try {
jsonObject.getJSONObject("data").getJSONObject("object").getString("invoice");
doesGettingStringWork = true;
}
catch (JSONException e) {
doesGettingStringWork = false;
}
Logger.log("The value of automatic charge is: " + isAutomaticCharge);
Logger.log("Geting the invoice worked? " + doesGettingStringWork);
Logger.log(jsonObject.getJSONObject("data").getJSONObject("object").toString());
if (isAutomaticCharge) {
handleFailedCharge(jsonObject);
}
else {
//Manual Charge
}
在生产中,以下数据导致 isAutomaticCharge 为真,而 doesGettingStringWork 为假:
{
"id": "evt_16vC0s1WJGsEk3Qvnstmq6fa",
"object": "event",
"api_version": "2014-03-28",
"created": 1444678274,
"data": {
"object": {
"id": "ch_16vC0r1WJGsEk3Qv5rxezNQj",
"object": "charge",
"amount": 1900,
"amount_refunded": 0,
"captured": false,
"card": {
"id": "card_16vC0k1WJGsEk3Qvl9LLEt5K",
"object": "card",
"brand": "MasterCard",
"country": "CA",
"customer": "cus_79V0ZH6qFFA4K0",
"cvc_check": "fail",
"exp_month": 9,
"exp_year": 2016,
"fingerprint": "ifxs23sixYzpKant",
"funding": "credit",
"last4": "6912",
"metadata": {},
"name": "derek@footbole.com",
"type": "MasterCard"
},
"created": 1444678273,
"currency": "usd",
"customer": "cus_79V0ZH6qFFA4K0",
"failure_code": "card_declined",
"failure_message": "Your card was declined.",
"fraud_details": {},
"livemode": true,
"metadata": {},
"paid": false,
"refunded": false,
"refunds": [],
"source": {
"id": "card_16vC0k1WJGsEk3Qvl9LLEt5K",
"object": "card",
"brand": "MasterCard",
"country": "CA",
"customer": "cus_79V0ZH6qFFA4K0",
"cvc_check": "fail",
"exp_month": 9,
"exp_year": 2016,
"fingerprint": "ifxs23sixYzpKant",
"funding": "credit",
"last4": "6912",
"metadata": {},
"name": "derek@footbole.com",
"type": "MasterCard"
},
"status": "failed"
}
},
"livemode": true,
"pending_webhooks": 2,
"request": "req_79V0v7433eb9hZ",
"type": "charge.failed"
}
当我在本地运行代码并为其提供 json 时,它按预期工作,isAutomaticCharge 和 doesGettingStringWork 都为假。
我正在运行 org.json 的 20140107 版本。我为每个请求声明了一个新的 JSONObject,因此线程应该不是问题。还有其他人在 Google App Engine 上运行 org.json 时遇到问题吗?