【问题标题】:Class com.fasterxml.jackson.datatype.joda.deser.DateTimeDeserializer has no default (no arg) constructorcom.fasterxml.jackson.datatype.joda.deser.DateTimeDeserializer 类没有默认(无 arg)构造函数
【发布时间】:2016-07-18 09:42:53
【问题描述】:

我收到一个错误 - “类 com.fasterxml.jackson.datatype.joda.deser.DateTimeDeserializer 没有默认(无 arg)构造函数”,而我正在尝试为发布请求调用 restangular。当我调用该方法时,它会进入错误块。

Restangular.all('tests').post($scope.test).then(function (data) {
                    $scope.test.id = data.id;
                    $location.path($location.path() + data.id).replace();
                }, function (error) {
                    $scope.exceptionDetails = validationMapper(error);
                });

我正在使用 jackson-datatype-joda - 2.6.5

该方法中使用的实体类如下-

@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@Entity
@Table(name = "Test")
@EqualsAndHashCode(of = "id", callSuper = false)
@ToString(exclude = {"keywords", "relevantObjectIds"})
public class Test {
    @Id
    @Column(unique = true, length = 36)
    private String id;

    @NotBlank
    @NotNull
    private String name;

    @Transient
    private List<Testabc> Testabcs = new ArrayList<>();

}

上述实体Testabc类中使用的实体类如下

@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@Slf4j
@Entity
@Table(name = "Test_abc")
@EqualsAndHashCode(of = "id", callSuper = false)
public class Testabc{
    @Id
    @Column(unique = true, length = 36)
    @NotNull
    private String id = UUID.randomUUID().toString();

 @Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime")
    @JsonDeserialize(using = DateTimeDeserializer.class)
    @JsonSerialize(using = DateTimeSerializer.class)
    private DateTime createdOn;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "Id")
    @NotNull
    private t1 pid;

    private long originalSize;
}

最后是我请求创建测试数据的资源类 -

@ApiOperation(value = "Create new Test", notes = "Create a new Test and return with its unique id", response = Test.class)
    @POST
    @Timed
    public Test create(Test newInstance) {
        return super.create(newInstance);
    }

我已经尝试添加这个 @JsonIgnoreProperties(ignoreUnknown = true) 在实体类上注解,但是不起作用。

谁能帮忙解决这个问题?

【问题讨论】:

  • 不,没有重复
  • 这是否意味着链接问题的答案和mapper.registerModule(new JodaModule()); 的建议解决方案对您不起作用?
  • 此链接 (stackoverflow.com/questions/36795151/…) 建议使用注释或上述帮助,我只想使用注释来完成这项工作。我需要使用 mapper.registerModule(new JodaModule());带注释?
  • 两种解决方案都表明DateTimeDeserializer 没有无参数构造函数,这确实是您的问题。如果您只想使用注释,您可以简单地自己扩展它并添加一个无参数构造函数,该构造函数使用必要的参数调用super

标签: java angularjs spring nhibernate-mapping


【解决方案1】:

查看DateTimeDeserializer 的最新来源可以很容易地看到它没有无参数构造函数,这似乎是框架所要求的。这在两个链接的问题中也有说明:joda.time.DateTime deserialization error & Jackson, Retrofit, JodaTime deserialization

由于您只想使用基于注释的解决方案,因此一种可能的解决方法是创建您自己的反序列化器,该反序列化器扩展 DateTimeDeserializer 并提供一个 nor-arg 构造函数。

1) MyDateTimeSerializer

import com.fasterxml.jackson.datatype.joda.cfg.FormatConfig;
import com.fasterxml.jackson.datatype.joda.deser.DateTimeDeserializer;
import org.joda.time.DateTime;

public class MyDateTimeDeserializer extends DateTimeDeserializer {
    public MyDateTimeDeserializer() {
        // no arg constructor providing default values for super call
        super(DateTime.class, FormatConfig.DEFAULT_DATETIME_PARSER);
    }
}

2) AClass 使用自定义解串器

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.joda.ser.DateTimeSerializer;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;

public class AClass {

    @JsonSerialize(using = DateTimeSerializer.class) // old serializer
    @JsonDeserialize(using = MyDateTimeDeserializer.class) // new deserializer
    private DateTime createdOn = DateTime.now(DateTimeZone.UTC); // some dummy data for the sake of brevity

    public DateTime getCreatedOn() {
        return createdOn;
    }

    public void setCreatedOn(DateTime createdOn) {
        this.createdOn = createdOn;
    }
}

3) 单元测试

import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;

public class ATest {
    @Test
    public void testSomeMethod() throws Exception {
        // Jackson object mapper to test serialization / deserialization
        ObjectMapper objectMapper = new ObjectMapper();

        // our object
        AClass initialObject = new AClass();

        // serialize it
        String serializedObject = objectMapper.writeValueAsString(initialObject);

        // deserialize it
        AClass deserializedObject = objectMapper.readValue(serializedObject, AClass.class);

        // check that the dates are equal (no equals implementation on the class itself...)
        assertThat(deserializedObject.getCreatedOn(), is(equalTo(initialObject.getCreatedOn())));
    }
}

【讨论】:

  • 谢谢,但它不起作用,仍然出现同样的错误
  • @Geetanjali 虽然有可能,但您在更改某些内容后不太可能遇到相同的异常,因为这意味着您的修改没有任何影响。您能否清理您的工作区/输出文件夹,重建您的应用程序,然后重试并共享异常消息和堆栈跟踪?
  • 感谢您的回复,但我已经尝试了您的建议,并确保我已经构建并清理了应用程序。另一件事是我没有任何堆栈跟踪,因为代码在进入 java 代码之前就中断了,它只是调用了 Restangular 的错误块,即 'Class com.fasterxml.jackson.datatype.joda.deser.DateTimeDeserializer has没有默认(无 arg)构造函数。
  • @Geetanjali 如果您在实体中将DateTimeDeserializer 替换为MyDateTimeDeserializer 并且遇到相同的异常,那么问题一定出在其他地方。在这种情况下,你能在github或类似的地方分享一个SSCCE的后端吗?
  • 抱歉,我不能分享我的代码,因为它是客户端代码。
【解决方案2】:

这个反序列化器从不打算被注释使用;正如其他人提到的那样,不能。一般来说,你真的应该只添加/注册JodaModule,然后按预期添加序列化器/反序列化器。

我不知道你为什么不想走那条路;可能值得扩展为什么这个解决方案 (或通过您的自定义模块注册您通过DateTimeDeserializer.forType(ReadableDateTime.class) 获得的反序列化器) 不适用。

【讨论】:

    猜你喜欢
    • 2017-08-30
    • 1970-01-01
    • 2019-04-13
    • 2022-01-01
    • 2023-03-20
    • 2016-07-18
    • 2011-12-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多