【问题标题】:Jackson: Can not deserialize instance of com.org.my_services.external_services.ifs.converter.InventoryPricePayload out of START_ARRAY tokenJackson:无法从 START_ARRAY 令牌中反序列化 com.org.my_services.external_services.ifs.converter.InventoryPricePayload 的实例
【发布时间】:2014-06-23 20:56:02
【问题描述】:

我尝试使用的有效负载看起来像

我有应该映射到上述JSON 有效负载的类列表。

InventoryPricePayload

@JsonIgnoreProperties(ignoreUnknown = true)
public class InventoryPricePayload {
    private List<InventoryPriceDetail> inventoryPriceDetails;

    @SuppressWarnings({ "RedundantNoArgConstructor", "UnusedDeclaration" })
    public InventoryPricePayload() {
        // used by Jackson
    }

    @Nonnull
    public List<InventoryPriceDetail> getInventoryPriceDetails() {
        return Collections.unmodifiableList(inventoryPriceDetails);
    }

    public void setInventoryPriceDetails(@Nonnull final List<InventoryPriceDetail> inventoryPriceDetails) {
        //noinspection AssignmentToCollectionOrArrayFieldFromParameter
        this.inventoryPriceDetails = inventoryPriceDetails;
    }
}

然后 InventoryPriceDetail

@JsonIgnoreProperties(ignoreUnknown = true)
public class InventoryPriceDetail {
    private List<InvListPriceData> invListPriceData;

    @SuppressWarnings({ "RedundantNoArgConstructor", "UnusedDeclaration" })
    public InventoryPriceDetail() {
        // used by Jackson
    }

    @Nonnull
    public List<InvListPriceData> getInvListPriceData() {
        return Collections.unmodifiableList(invListPriceData);
    }

    public void setInvListPriceData(@Nonnull final List<InvListPriceData> invListPriceData) {
        //noinspection AssignmentToCollectionOrArrayFieldFromParameter
        this.invListPriceData = invListPriceData;
    }
}

最后是 InvListPriceData

@JsonIgnoreProperties(ignoreUnknown = true)
public class InvListPriceData {
    private BigInteger total;
    private BigInteger available;
    private BigInteger bookable;

    @SuppressWarnings({ "UnusedDeclaration", "RedundantNoArgConstructor" })
    public InvListPriceData() {
        // used by Jackson
    }

    @Nonnull
    public BigInteger getTotal() {
        return total;
    }

    public void setTotal(@Nonnull final BigInteger total) {
        this.total = total;
    }

    @Nonnull
    public BigInteger getAvailable() {
        return available;
    }

    public void setAvailable(@Nonnull final BigInteger available) {
        this.available = available;
    }

    @Nonnull
    public BigInteger getBookable() {
        return bookable;
    }

    public void setBookable(@Nonnull final BigInteger bookable) {
        this.bookable = bookable;
    }
}

我尝试test这个喜欢

final ObjectMapper mapper = new ObjectMapper();
        try {
            final InventoryPricePayload inventoryPricePayload = mapper.readValue(new File(getClass().getResource("/getInventoryAndPrice.json").getPath()), InventoryPricePayload.class);
            System.out.println(inventoryPricePayload);
        } catch (final IOException e) {
           throw new RuntimeException("can not read resource :" + e.getMessage());
        }

我得到如下失败:

Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.742 sec <<< FAILURE! - in com.org.my_services.external_services.ifs.IFSManagerTest
testMockIfsClient(com.org.my_services.external_services.ifs.IFSManagerTest)  Time elapsed: 0.615 sec  <<< ERROR!
java.lang.RuntimeException: can not read resource :Can not deserialize instance of com.org.my_services.external_services.ifs.converter.InventoryPricePayload out of START_ARRAY token
 at [Source: /Users/harith/IdeaProjects/my_services/external_services/ifs/target/test-classes/getInventoryAndPrice.json; line: 1, column: 1]
    at com.org.my_services.external_services.ifs.MockIfsClient.getInventoryAndPrice(MockIfsClient.java:25)
    at com.org.my_services.external_services.ifs.IFSManager.getInventoryAndPrice(IFSManager.java:20)
    at com.org.my_services.external_services.ifs.IFSManagerTest.testMockIfsClient(IFSManagerTest.java:28)

问题

我到底在哪里搞砸了?

【问题讨论】:

    标签: java json spring jackson object-object-mapping


    【解决方案1】:

    根据 Jackson documentation(请参阅使用泛型的数据绑定),我做了以下事情并且一切正常

    final List<InventoryPriceDetail> inventoryPriceDetails= mapper.readValue(new File(getClass().getResource("/getInventoryAndPrice.json").getPath()), new TypeReference<List<InventoryPriceDetail>>() {});
    

    【讨论】:

      【解决方案2】:

      而不是使用

      new TypeReference&lt;List&lt;InventoryPriceDetail&gt;&gt;() {}

      这有点难看,因为你也可以使用类实现

      mapper.getTypeFactory().constructCollectionType(List.class, InventoryPriceDetail.class)

      【讨论】:

      • 个人意见:TypeReference 使结构更具可读性。
      • @daydreamer 我想这是见仁见智 :)
      猜你喜欢
      • 2015-01-04
      • 2020-06-16
      • 1970-01-01
      • 2020-09-23
      • 1970-01-01
      • 2016-07-30
      • 2015-03-10
      • 2019-10-25
      • 2015-12-24
      相关资源
      最近更新 更多