JsonMappingException:当前令牌不是START_OBJECT(需要解包根名'Transaction []'),而是START_ARRAY [英] JsonMappingException: Current token not START_OBJECT (needed to unwrap root name 'Transaction[]'), but START_ARRAY

查看:53
本文介绍了JsonMappingException:当前令牌不是START_OBJECT(需要解包根名'Transaction []'),而是START_ARRAY的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Spring的 Chargify API .它一直进行得很顺利,但是当我尝试获取一个对象数组时,它不幸失败了.例如,考虑以下内容:

I'm using Spring's RestTemplate to consume the Chargify API, using JSON as the payload format. It has been going pretty smoothly, however when I try to GET an array of objects it fails miserably. For example, consider the following:

Transaction[] transactions = restTemplate.getForObject(
        CHARGIFY_ENDPOINT + "/subscriptions/{subscription}/transactions.json",
        Transaction[].class,
        subscriptionId
    );

实际的GET进行得很顺利,其JSON响应为:

The actual GET goes thru fine, with a JSON response of:

[ { "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"
      } }
]

但是,当Jackson尝试反序列化JSON时,结果为JsonMappingException: Current token not START_OBJECT (needed to unwrap root name 'Transaction[]'), but START_ARRAY:

However, when Jackson attempts to deserialize the JSON, it results in 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.springframework.http.converter.json.MappingJacksonHttpMessageConverter@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 org.apache.http.impl.conn.SingleClientConnManager$ConnAdapter@17ed710
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: org.apache.http.conn.EofSensorInputStream@598a5d; 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: org.apache.http.conn.EofSensorInputStream@598a5d; 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: org.apache.http.conn.EofSensorInputStream@598a5d; 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: org.apache.http.conn.EofSensorInputStream@598a5d; 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: org.apache.http.conn.EofSensorInputStream@598a5d; 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: org.apache.http.conn.EofSensorInputStream@598a5d; line: 1, column: 1]

我在与杰克逊(Jackson)之前就遇到过这个问题,在花了几天的研究之后,我最终走了一条不同的路.这次这不是一个选择,我也没有运气找到解决方案.

I ran into this issue before with Jackson, and after spending a couple days of research I ended up going a different route. That is not an option this time, and I'm having no luck figuring out a solution.

有什么想法吗?我不在乎是否返回数组或List.我也没有运气.

Any ideas? I don't care if I get an array or a List back. I haven't had luck with either.

在阅读杰克逊的文档时,我看到了应该在哪里包装列表,即new TypeReference<List<Transaction>>(),但是我也没有运气.

While reading Jackson's docs, I saw where you should be able to wrap the list, i.e. new TypeReference<List<Transaction>>(), but I had no luck there either.

顺便说一句,由于Chargify如何格式化其JSON响应,我的RestTemplate配置了自定义

BTW, because of how Chargify formats their JSON responses my RestTemplate is configured with a custom ObjectMapper that sets these options:

configure(SerializationConfig.Feature.WRAP_ROOT_VALUE, true);
configure(DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true);

当我删除这些选项时,没有抛出JsonMappingException,但是生成的Transaction对象的所有字段均为空.

When I remove these options, no JsonMappingException is thrown however all of the fields of the resulting Transaction objects are null.

我也尝试添加此选项,但似乎无济于事:

I also tried adding this option, but it does not seem to help:

configure(DeserializationConfig.Feature.USE_JAVA_ARRAY_FOR_JSON_ARRAY, true);

推荐答案

您只需要在Transaction顶部添加其他包装类型,也请删除UNWRAP_ROOT_VALUE选项.

You just need another wrapper type on top of Transaction, also please remove the UNWRAP_ROOT_VALUE option.

这些类将遵循以下原则:

The classes will be along these lines:

public class TransactionHolder {
    private Transaction transaction;
... 
}

public class Transaction {
    private String amount_in_cents;
    private String created_at;
    private int ending_balance_in_cents;
    private int id;
    private String kind;
    private String memo;
    private int payment_id;
    private int product_id;
    private int subscription_id;
    private boolean success;
    private String transaction_type;
    private String type;
...
}

对于您的示例json,以下内容对我来说很干净:

With your sample json, the following works for me cleanly:

ObjectMapper mapper = new ObjectMapper();
InputStream is = this.getClass().getResourceAsStream("sample.json");
TransactionHolder[] holders = mapper.readValue(is,TransactionHolder[].class); 

这篇关于JsonMappingException:当前令牌不是START_OBJECT(需要解包根名'Transaction []'),而是START_ARRAY的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆