我收到错误 - '类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)注释,但它不起作用。
任何人都可以帮忙解决这个问题吗?
答案 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())));
}
}