无法序列化 (json) 对象,因为 weld 创建代理 "Unrecognized field " 处理程序”
Can't serialize (json) object because weld creates a proxy "Unrecognized field "handler"
我的项目中有许多 DTO classes 序列化为 json 以用于休息端点。所有扩展(直接或间接)抽象 class "Linkable" 保存对象的 id 并使用注入 "UriInfo" 创建自我 link。
为了让它工作,我需要注入 DTO 的实例。这一切都很好。
最近我创建了另外 2 个 DTO,它们在层次结构中有一个额外的级别。问题是,如果我尝试注入这个 classes 的实例,我会得到一个代理(由焊接创建)。此代理包含无法序列化的其他字段,因为它们是未知的(没有 getter 或 setter):
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "handler"
所以我的问题是:为什么要实例化代理而不是 class 本身。 作为解决方法:我可以将这些附加字段标记为以某种方式忽略吗(代理是子class)?
这是与工作 DTO 不同的层次结构部分的代码(CreatedByUserRepresentation extends Linkable):
public abstract class VoteRepresentation<T extends CreatedByUserRepresentation> extends CreatedByUserRepresentation{
@NotNull
private T voteOf;
@Min(-1) // down vote
@Max(1) // up vote
private int value;
@AssertTrue
public boolean valueIsNotZero() {
return value != 0;
}
public T getVoteOf() {
return voteOf;
}
public int getValue() {
return value;
}
public void setVoteOf(T voteOf) {
this.voteOf = voteOf;
}
public void setValue(int value) {
this.value = value;
}
}
实际class:
@XmlRootElement(name = "problemvote", namespace = "urn:problems:problemvote")
public class ProblemVoteRepresentation extends VoteRepresentation<ProblemRepresentation> {
@Override
protected Class<?> getResourceClass() {
return ProblemVoteResource.class;
}
}
"VoteRepresentation"还有一个扩展名。两者都有相同的问题:通过 cdi 我只能获得 "proxy" 具有不可序列化的附加字段的实例。
获得一些线索就足够了,为什么有时会使用代理。我只读了范围。但在这种情况下,注入 dto 的 class 都是 "RequestScoped"。
我找到了这种奇怪行为的原因:它是注释 @AssertTrue
。如果我删除它,焊接将不再使用代理并且序列化工作正常。
这极大地限制了 javax.validation 的使用,我认为这种行为不是故意的?!
编辑
Martin Kouba gave a good explanation this behavior is implied by the bean validation spec 10.1.2.
我在使用对象映射器反序列化 json 时发生了这种情况,我仍然不知道为什么会发生,但肯定不是因为 @assertTrue 注释,
我使用 @JsonIgnoreProperties(ignoreUnknown = true).
解决了这个问题
我的项目中有许多 DTO classes 序列化为 json 以用于休息端点。所有扩展(直接或间接)抽象 class "Linkable" 保存对象的 id 并使用注入 "UriInfo" 创建自我 link。 为了让它工作,我需要注入 DTO 的实例。这一切都很好。
最近我创建了另外 2 个 DTO,它们在层次结构中有一个额外的级别。问题是,如果我尝试注入这个 classes 的实例,我会得到一个代理(由焊接创建)。此代理包含无法序列化的其他字段,因为它们是未知的(没有 getter 或 setter):
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "handler"
所以我的问题是:为什么要实例化代理而不是 class 本身。 作为解决方法:我可以将这些附加字段标记为以某种方式忽略吗(代理是子class)?
这是与工作 DTO 不同的层次结构部分的代码(CreatedByUserRepresentation extends Linkable):
public abstract class VoteRepresentation<T extends CreatedByUserRepresentation> extends CreatedByUserRepresentation{
@NotNull
private T voteOf;
@Min(-1) // down vote
@Max(1) // up vote
private int value;
@AssertTrue
public boolean valueIsNotZero() {
return value != 0;
}
public T getVoteOf() {
return voteOf;
}
public int getValue() {
return value;
}
public void setVoteOf(T voteOf) {
this.voteOf = voteOf;
}
public void setValue(int value) {
this.value = value;
}
}
实际class:
@XmlRootElement(name = "problemvote", namespace = "urn:problems:problemvote")
public class ProblemVoteRepresentation extends VoteRepresentation<ProblemRepresentation> {
@Override
protected Class<?> getResourceClass() {
return ProblemVoteResource.class;
}
}
"VoteRepresentation"还有一个扩展名。两者都有相同的问题:通过 cdi 我只能获得 "proxy" 具有不可序列化的附加字段的实例。 获得一些线索就足够了,为什么有时会使用代理。我只读了范围。但在这种情况下,注入 dto 的 class 都是 "RequestScoped"。
我找到了这种奇怪行为的原因:它是注释 @AssertTrue
。如果我删除它,焊接将不再使用代理并且序列化工作正常。
这极大地限制了 javax.validation 的使用,我认为这种行为不是故意的?!
编辑 Martin Kouba gave a good explanation this behavior is implied by the bean validation spec 10.1.2.
我在使用对象映射器反序列化 json 时发生了这种情况,我仍然不知道为什么会发生,但肯定不是因为 @assertTrue 注释, 我使用 @JsonIgnoreProperties(ignoreUnknown = true).
解决了这个问题