我使用Spring的RestTemplate消耗Chargify API,使用JSON作爲有效負載格式。它一直很順利,但是當我嘗試獲取一組對象時,它失敗了。例如,考慮以下因素:JsonMappingException:當前令牌不是START_OBJECT(需要展開根名稱'Transaction []'),但START_ARRAY
Transaction[] transactions = restTemplate.getForObject(
CHARGIFY_ENDPOINT + "/subscriptions/{subscription}/transactions.json",
Transaction[].class,
subscriptionId
);
實際GET會突破微細,爲的JSON響應:
[ { "transaction" : { "amount_in_cents" : 3006,
"created_at" : "2012-06-17T16:32:05-04:00",
"ending_balance_in_cents" : 0,
"id" : 17283728,
"kind" : null,
"memo" : "",
"payment_id" : null,
"product_id" : 120387,
"subscription_id" : 1947292,
"success" : true,
"transaction_type" : "payment",
"type" : "Payment"
} },
{ "transaction" : { "amount_in_cents" : 5900,
"created_at" : "2012-06-17T16:32:05-04:00",
"ending_balance_in_cents" : 3006,
"id" : 17283727,
"kind" : "baseline",
"memo" : "Professional Plan (06/17/2012 - 07/17/2012)",
"payment_id" : 17283728,
"product_id" : 120387,
"subscription_id" : 1947292,
"success" : true,
"transaction_type" : "charge",
"type" : "Charge"
} },
{ "transaction" : { "amount_in_cents" : -2894,
"created_at" : "2012-06-17T16:32:03-04:00",
"ending_balance_in_cents" : -2894,
"id" : 17283726,
"kind" : "prorated",
"memo" : "",
"payment_id" : null,
"product_id" : 120387,
"subscription_id" : 1947292,
"success" : null,
"transaction_type" : "adjustment",
"type" : "Adjustment"
} },
{ "transaction" : { "amount_in_cents" : 2900,
"created_at" : "2012-06-17T15:17:07-04:00",
"ending_balance_in_cents" : 0,
"id" : 17281084,
"kind" : null,
"memo" : "",
"payment_id" : null,
"product_id" : 120386,
"subscription_id" : 1947292,
"success" : true,
"transaction_type" : "payment",
"type" : "Payment"
} },
{ "transaction" : { "amount_in_cents" : 2900,
"created_at" : "2012-06-17T15:17:06-04:00",
"ending_balance_in_cents" : 2900,
"id" : 17281083,
"kind" : "baseline",
"memo" : "Standard Plan (06/17/2012 - 07/17/2012)",
"payment_id" : 17281084,
"product_id" : 120386,
"subscription_id" : 1947292,
"success" : true,
"transaction_type" : "charge",
"type" : "Charge"
} }
]
然而,當傑克遜試圖反序列化JSON,它導致JsonMappingException: Current token not START_OBJECT (needed to unwrap root name 'Transaction[]'), but START_ARRAY
:
16:59:12.651 [http-8080-1] DEBUG org.springframework.web.client.RestTemplate - GET request for "https://foobar.chargify.com/subscriptions/1947292/transactions.json" resulted in 200 (OK)
16:59:12.651 [http-8080-1] DEBUG org.springframework.web.client.RestTemplate - Reading [[Lcom.foobar.chargify.Transaction;] as "application/json;charset=utf-8" using [org.springf[email protected]1ea8dbd]
16:59:12.662 [http-8080-1] DEBUG org.apache.http.wire - << "[{"transaction":{"type":"Payment","amount_in_cents":3006,"payment_id":null,"memo":"","id":17283728,"created_at":"2012-06-17T16:32:05-04:00","subscription_id":1947292,"kind":null,"ending_balance_in_cents":0,"success":true,"product_id":120387,"transaction_type":"payment"}},{"transaction":{"type":"Charge","amount_in_cents":5900,"payment_id":17283728,"memo":"Professional Plan (06/17/2012 - 07/17/2012)","id":17283727,"created_at":"2012-06-17T16:32:05-04:00","subscription_id":1947292,"kind":"baseline","ending_balance_in_cents":3006,"success":true,"product_id":120387,"transaction_type":"charge"}},{"transaction":{"type":"Adjustment","amount_in_cents":-2894,"payment_id":null,"memo":"","id":17283726,"created_at":"2012-06-17T16:32:03-04:00","subscription_id":1947292,"kind":"prorated","ending_balance_in_cents":-2894,"success":null,"product_id":120387,"transaction_type":"adjustment"}},{"transaction":{"type":"Payment","amount_in_cents":2900,"payment_id":null,"memo":"","id":17281084,"created_at":"2012-06-17T15:17:07-04:00","subscription_id":1947292,"kind":null,"ending_balance_in_cents":0,"success":true,"product_id":120386,"transaction_type":"payment"}},{"transaction":{"type":"Charge","amount_in_cents":2900,"payment_id":17281084,"memo":"Standard Plan (06/17/2012 - 07/17/2012)","id":17281083,"created_at":"2012-06-17T15:17:06-04:00","subscription_id":1947292,"kind":"baseline","ending_balance_in_cents":2900,"success":true,"product_id":120386,"transaction_type":"charge"}}]"
16:59:12.683 [http-8080-1] DEBUG org.apache.http.impl.conn.SingleClientConnManager - Releasing connection [email protected]ed710
16:59:12.684 [http-8080-1] DEBUG org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - Resolving exception from handler [public void com.foobar.controllers.TestController.viewTransactions(int)]: org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Current token not START_OBJECT (needed to unwrap root name 'Transaction[]'), but START_ARRAY
at [Source: [email protected]; line: 1, column: 1]; nested exception is org.codehaus.jackson.map.JsonMappingException: Current token not START_OBJECT (needed to unwrap root name 'Transaction[]'), but START_ARRAY
at [Source: [email protected]; line: 1, column: 1]
16:59:12.686 [http-8080-1] DEBUG org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver - Resolving exception from handler [public void com.foobar.controllers.TestController.viewTransactions(int)]: org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Current token not START_OBJECT (needed to unwrap root name 'Transaction[]'), but START_ARRAY
at [Source: [email protected]; line: 1, column: 1]; nested exception is org.codehaus.jackson.map.JsonMappingException: Current token not START_OBJECT (needed to unwrap root name 'Transaction[]'), but START_ARRAY
at [Source: [email protected]; line: 1, column: 1]
16:59:12.686 [http-8080-1] DEBUG org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Resolving exception from handler [public void com.foobar.controllers.TestController.viewTransactions(int)]: org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Current token not START_OBJECT (needed to unwrap root name 'Transaction[]'), but START_ARRAY
at [Source: [email protected]; line: 1, column: 1]; nested exception is org.codehaus.jackson.map.JsonMappingException: Current token not START_OBJECT (needed to unwrap root name 'Transaction[]'), but START_ARRAY
at [Source: [email protected]; line: 1, column: 1]
我之前和傑克遜一起遇到過這個問題,經過幾天的研究,我最終走上了一條不同的路線。這次不是一個選擇,我沒有找到解決方案的運氣。
任何想法?我不在乎是否獲得陣列或返回List
。我還沒有碰運氣。
在閱讀傑克遜的文檔時,我看到了你應該能夠包裝清單的位置,即new TypeReference<List<Transaction>>()
,但我也沒有運氣。
BTW,因爲Chargify如何格式的JSON響應我的RestTemplate配置了一個自定義ObjectMapper
,設置這些選項:
configure(SerializationConfig.Feature.WRAP_ROOT_VALUE, true);
configure(DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true);
當我刪除這些選項,沒有JsonMappingException
被拋出但是所有的領域由此產生的Transaction
對象爲空。
我也想加入這個選項,但它似乎並沒有幫助:
configure(DeserializationConfig.Feature.USE_JAVA_ARRAY_FOR_JSON_ARRAY, true);
謝謝,我還沒來得及尚未進行測試。與此同時,你能解釋爲什麼這需要一個包裝類,但單個事務JSON對象不會 - 即使單個事務JSON對象也被包裝,即。 {「transaction」:{...}}?的確,唯一的區別是數組包含了其中的很多。這對我來說是如此令人困惑。另外,爲什麼這不需要UNWRAP_ROOT_VALUE選項?再次感謝! :) –
其實,它只是爲我點擊! UNWRAP_ROOT_VALUE選項不是必需的,因爲與單個事務JSON對象不同,數組不包含在無名包裝器對象中。所以沒有什麼可以解開的,並且試圖這樣做會拋出我以前遇到的異常。其次,TransactionHolder類是需要的,因爲數組元素沒有UNWRAP_ROOT_ELEMENT等價物;我們必須使用TransactionHolder自己解包它們。我對嗎? –
是的,正好@TheAwnryBear,你沒有一個包裝的根,所以在反序列化時不需要UNWRAP_ROOT_VALUE。在沒有交易持有人的情況下直接填充交易對象,我認爲可以用傑克遜來完成,但不知道如何離手。 –