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

时间:2016-07-18 09:42:54

标签: java angularjs spring nhibernate-mapping

我收到错误 - '类com.fasterxml.jackson.datatype.joda.deser.DateTimeDeserializer没有默认(无arg)构造函数',而我正在尝试为post请求调用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)注释,但它不起作用。

任何人都可以帮忙解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

查看DateTimeDeserializer的最新来源,您可以很容易地看到它没有no-arg构造函数,这似乎是框架所需要的。这两个相关问题也表明了这一点:joda.time.DateTime deserialization error&amp; 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())));
    }
}