Jackson、Retrofit、JodaTime 反序列化

2024-01-03

我正在使用这三个库:retrofit、jackson 和 jodatime,并且当对象来自我的 Rest api 时,我正在尝试反序列化我的对象,但我不知道如何解决这个问题,这里是 Rest 返回的 json应用程序编程接口:

{
    "establishment": "Gold Ball Confraria",
    "idCardPayment": 0,
    "paymentDate": "/Date(1461208761970+0000)/",
    "total": 10
}

这就是我尝试反序列化我的对象的类:

public class PaymentHistoryItemApiResult {

    @JsonProperty("total")
    private double totalValue;
    @JsonProperty("establishment")
    private String establishmentName;
    @JsonDeserialize(using = DateTimeDeserializer.class)
    private DateTime paymentDate;
    private long idCardPayment;

    public PaymentHistoryItemApiResult() {

    }

    public PaymentHistoryItemApiResult(double totalValue, String establishmentName, DateTime paymentDate, long idCardPayment) {
        this.totalValue = totalValue;
        this.establishmentName = establishmentName;
        this.paymentDate = paymentDate;
        this.idCardPayment = idCardPayment;
    }
... getters/setters

}

API端点:

    @GET("User.svc/{idUser}/payment/history")
    Call<PaymentHistoryItemApiResult> getPaymentHistory(@Path("idUser") long idUser);

单元测试中如何调用它:

@Test
public void getPaymentHistoryTest(){

    Response<PaymentHistoryItemApiResult> info = null;
    try {
        info = UserRequester.userRequester.getPaymentHistory(153).execute();

        PaymentHistoryItemApiResult res = info.body();
        Assert.assertNotNull(res);

    } catch (IOException e) {
        e.printStackTrace();
    }

}

错误:

com.fasterxml.jackson.databind.JsonMappingException: Class com.fasterxml.jackson.datatype.joda.deser.DateTimeDeserializer has no default (no arg) constructor
 at [Source: java.io.InputStreamReader@525b461a; line: 1, column: 1]
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:251)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:269)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
    at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
    at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:477)
    at com.fasterxml.jackson.databind.ObjectReader._findRootDeserializer(ObjectReader.java:1813)
    at com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:1570)
    at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1183)
    at retrofit2.converter.jackson.JacksonResponseBodyConverter.convert(JacksonResponseBodyConverter.java:32)
    at retrofit2.converter.jackson.JacksonResponseBodyConverter.convert(JacksonResponseBodyConverter.java:23)
    at retrofit2.ServiceMethod.toResponse(ServiceMethod.java:116)
    at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:211)
    at retrofit2.OkHttpCall.execute(OkHttpCall.java:174)
    at br.com.soutsapp.user.souts.WCFClientTest.getPaymentHistoryTest(WCFClientTest.java:96)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.lang.IllegalArgumentException: Class com.fasterxml.jackson.datatype.joda.deser.DateTimeDeserializer has no default (no arg) constructor
    at com.fasterxml.jackson.databind.util.ClassUtil.createInstance(ClassUtil.java:594)
    at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.deserializerInstance(DefaultDeserializationContext.java:234)
    at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findDeserializerFromAnnotation(BasicDeserializerFactory.java:1772)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.constructSettableProperty(BeanDeserializerFactory.java:728)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.addBeanProps(BeanDeserializerFactory.java:506)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:228)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:143)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:406)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:352)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264)
    ... 38 more

预先感谢,任何帮助将不胜感激。


第一视角分析:

您的代码中存在一些问题。您提供的时间"/Date(1461208761970+0000)/"看起来不熟悉。您也有一些代码问题。您的构造函数无法与 joda 构造函数正确对话

根本原因:

您的问题:

com.fasterxml.jackson.databind.JsonMappingException:类 com.fasterxml.jackson.datatype.joda.deser.DateTimeDeserializer 没有 默认(无参数)构造函数

是从您的代码生成的:

 at br.com.soutsapp.user.souts.WCFClientTest.getPaymentHistoryTest(WCFClientTest.java:96)

问题分析:

将值反序列化为org.joda.time.DateTime你必须定义@JsonDeserialize因为杰克逊无法弄清楚使用了什么方法/构造函数org.joda.time.DateTime从字符串值初始化它。

解决方案 - 1:

您需要使用序列化和反序列化。您应该检查 jar 可用性并应将读取类型设置为 JSON。

您可以按照以下 3 个步骤操作。

  1. 您需要使用序列化和反序列化。您的日期模式应类似于 Json 格式。

代码将是

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
@JsonSerialize(using = DateTimeSerializer.class)
@JsonDeserialize(using = DateTimeDeserializer.class)
private DateTime paymentDate;
  1. 确保您在类路径上jackson-datatype-joda.

  2. 将 SSM 配置更改为默认使用 JSON 格式(在 默认MemcachedClient定义):

    <property name="defaultSerializationType" value="JSON" />

资源链接:

https://github.com/ragnor/simple-spring-memcached/issues/41 https://github.com/ragnor/simple-spring-memcached/issues/41


解决方案 - 2:

您还可以添加另一个构造函数。这可能会产生影响。

 public PaymentHistoryItemApiResult() {
        super();
   }

资源链接:以下 2 个链接包含更多错误分析和解决方案

  1. 杰克逊例外——问题和解决方案 http://www.baeldung.com/jackson-exception
  2. Jackson – JsonMappingException(找不到类的序列化器) http://www.baeldung.com/jackson-jsonmappingexception

另一个解决方案:

如果您不想使用反序列化,则可以按照以下详细信息进行操作:

@JsonDeserialize期望一个JsonDeserializer使用无参数构造函数。 DateTimeDeserializer 的最新版本没有这样的构造函数。

如果您已经修复了格式,即。 yourTimestamp 应该只是一个时间戳,那么你可以简单地注册JodaModuleObjectMapper。它将在内部对 DateTime 字段使用 DateTimeDeserializer。您可以摆脱 @JsonDeserialize 注释。

mapper.registerModule(new JodaModule());

您需要添加jackson-datatype-joda图书馆。

资源链接:

  1. joda.time.DateTime 反序列化错误 https://stackoverflow.com/questions/22643367/joda-time-datetime-deserialization-error

用于空值序列化和反序列化 https://stackoverflow.com/questions/25404703/how-to-deserialize-joda-datetime-using-jackson-with-jersey-2-client-in-spring-mv

如果不想序列化空值,可以在序列化时使用以下设置:

objectMapper.setSerializationInclusion(Include.NON_NULL);

对于反序列化,杰克逊理想情况下应该能够处理序列化输出中的空值。

信用归@jackall https://stackoverflow.com/users/2428558/jackall

或者你也可以在你的类中使用注释。

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(Include.NON_NULL)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Jackson、Retrofit、JodaTime 反序列化 的相关文章

随机推荐

  • svnblame引起的声纳分析时jenkins出错

    当我运行詹金斯任务时 出现以下错误 17 12 49 738 INFO Sensor SCM Sensor 17 12 49 847 INFO SCM provider for this project is svn 17 12 49 84
  • switch case 语句内的表达式

    我正在尝试创建一个 switch 语句 但我似乎无法使用被评估的表达式 而不是设置的字符串 整数 我可以使用 if 语句轻松做到这一点 但 case 应该会更快 我正在尝试以下操作 function reward amount var re
  • 在带有 MacPorts 的 Snow Leopard 上使用 postgresql84 和 postgis 时没有 liblwgeom

    我正在尝试在升级到 Snow Leopard 后恢复并运行我的开发环境 特别是 我需要 postgresql 和 postgis 工作 但我遇到了以下问题 安装完两者后 sudo port install postgresql84 post
  • Git 无法锁定引用“HEAD”:无法解析引用 HEAD

    我正在尝试将更改提交到我的存储库 但收到以下错误 git c diff mnemonicprefix false c core quotepath false commit q F C Users Contronym AppData Loc
  • django 和 mongodb 会让迁移成为过去吗?

    由于 mongo 没有模式 这是否意味着我们在更改模型时不必进行迁移 非关系数据库的迁移过程是什么样的 我认为这是一个非常好的问题 但根据您正在使用的库和您对 迁移 的期望 答案会有点分散 让我们看一下一些常见的迁移操作 添加一个字段 Mo
  • 通过pid查找task_struct的有效方法

    有没有一种有效的方法可以找到task struct对于指定的 PID 无需迭代task struct list 使用以下其中一项有什么问题吗 extern struct task struct find task by vpid pid t
  • 找不到要导入的项目

    我正在寻找 Android 中的 ePub 阅读器 我提到翻页机 http www pageturner reader org downloads 下载了它的 apk 并且它有效 但是当我下载它的源代码时github https githu
  • 如何使用 javascript 获取 MVC 应用程序的基本 URL

    如何使用 javascript 获取基本 URL 例如 当我从 Visual Studio 浏览我的网站时 如果我的 URL 是http localhost 20201 home index 我想得到http localhost 20201
  • 带 CriteriaQuery 的 where 子句中的子查询

    任何人都可以给我一些关于如何将这种子查询放入CriteriaQuery 我在用着JPA 2 0 休眠 4 x SELECT a b c FROM tableA WHERE a SELECT d FROM tableB WHERE table
  • 根据另一个数组的顺序对数组子键进行排序

    我知道有很多关于数组排序的帖子 但我到处寻找 找不到解决我的问题的方法 我在这里找到了一篇非常好的文章 http firsttube com read sorting a multi Dimension array with php htt
  • 如何以编程方式获取标签栏的高度?

    我发现 UITabBar 的高度是 49px 或 50px 取决于源 因为我不喜欢在代码中使用太多硬编码值 所以我想知道是否可以以编程方式检索选项卡栏的高度 亲切的问候 尼尔斯 R PS 我问的原因是因为我有一个视图控制器 带有包含文本字段
  • 对计算列进行非规范化时需要权衡哪些因素?

    我希望我没有在这里问一个太明显的问题 对于我当前的项目 我正在使用 sql server 2008 设计一个相对简单的数据库 对于其中一个表 我决定引入 计算列 未持久化 它的表达式只是其他两个数字列的乘积 其存在的唯一原因是方便 我正在对
  • C# 应用程序被检测为病毒

    对于相同的程序我几分钟前的问题 https stackoverflow com questions 20061 store data from a c application 我添加了一个安装项目并为该程序构建了一个 MSI 只是为了看看我
  • 如何在 Linq 和 Entity Framework 5 中使用 DbGeography.Filter?

    使用 Entity Framework 5 可以在 Linq 查询中使用 SQL Server Spatial 过程 例如 使用 DbGeography 对象 您可以使用 Buffer 方法 该方法将转换为 SQL Server 中的 ST
  • 使用什么数据结构来在 PL/SQL 中对数据进行排序?

    这是Oracle 11 2g 在 PL SQL 函数中 我有一个循环 每次迭代时我都会创建一个字符串和与该字符串关联的整数 该函数返回所有生成的字符串的最终串联 并按字母顺序或按整数值排序 取决于函数输入参数 为了给出一个想法 我正在生成这
  • 如何使用 python 在 {} 中循环字典

    这是我的代码 a 0 000000 1 11111 3 333333 4 444444 b i j www for i j in a items print b 它显示错误 File g py line 7 b i j www for i
  • 仅允许来自特定域的请求读取和写入 Firebase 数据

    我最近开始使用 firebase 来存储数据 并将我的规则暂时设置为公开 我不想添加用户身份验证 而是想知道是否可以设置 firebase 规则 以便只有我的域可以读取和写入数据 限制某些用户访问实时数据库的唯一方法是通过 Firebase
  • 删除 int 数组中重复项的程序

    我编写了一些代码来从整数数组中删除重复项 我不想使用任何内置关键字 属性 这是我的逻辑 int iArray 1 2 3 2 3 4 3 int t 0 int arraysize iArray Length for int m 0 m l
  • ModalViewController 加载在另一个 Modal 之上

    可能有更好的方法来做到这一点 如果有请指导我 我正在创建一个UIImagePickerController在 viewDidAppear 中使用 overrideView 来表示 从库中选择 拍照 闪光灯 相机源 等 Set up the
  • Jackson、Retrofit、JodaTime 反序列化

    我正在使用这三个库 retrofit jackson 和 jodatime 并且当对象来自我的 Rest api 时 我正在尝试反序列化我的对象 但我不知道如何解决这个问题 这里是 Rest 返回的 json应用程序编程接口 establi