【问题标题】:Jackson deserialize an object that implements an interface and ignore the interface properties杰克逊反序列化实现接口的对象并忽略接口属性
【发布时间】:2018-03-03 02:45:29
【问题描述】:

我有一个带注释的类,它实现了一个带有名为.id()只读 属性的接口,该属性是通用的,因此我可以在其他部分提取不同类型的ids程序。

杰克逊应该忽略整个界面。但相反,我收到以下错误消息:

java.util.concurrent.ExecutionException: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: 不能 构造my.company.Identifiable 的实例(没有创作者, 像默认构造,存在):抽象类型要么需要 映射到具体类型,具有自定义反序列化器,或包含 [来源:未知;其他类型信息;行:-1,列: -1](通过引用链:java.util.HashSet[0]

在搜索该异常时,我已经尝试了此处找到的所有解决方案以及 Google 的前两页。他们都没有解决我遇到的确切问题,我无法从他们中的任何一个中插入针对我的具体问题的解决方案,除了我不想写的CustomDeserializer

我尝试使用JsonTypeInfo,但我以前从未使用过该注释,并且无法弄清楚我应该用它做什么。使用的解决方案与我的略有不同,他们实际上想要接口属性而不是忽略它。

在某些类中没有实际的id 成员变量,它只是一个method 来返回被视为程序另一部分的id 的东西。 ID<String> 在某些情况下,ID<Integer> 在其他情况下。

我尝试使用 @JsonProperty(access = Access.READ_ONLY) 以及 @JsonIgnore@JsonIgnoreProperties({"id"}) 进行注释,它们都没有改变异常。我还尝试了@JsonCreator 中的所有mode 设置,都没有成功。

接口定义为:

@JsonIgnoreProperties({"id"})
public interface Identifiable<T>
{
    @JsonIgnore
    public T id();
}

一个示例类定义为:

@JsonIgnoreProperties(ignoreUnknown = true)
public class User implements Identifiable<ID<String>>
{
    @JsonCreator
    public User(@JsonProperty("LoginName") final String loginName,
                @JsonProperty("Title") final String name,
                @JsonProperty("Email") final String email)
/* lots of irrelevant code redacted */

    @JsonIgnore
    @Override
    public ID<String> id()
    {
        return new ID.from(this.name);
    }
}

绑定代码如下所示:

final HttpResponse response = req.execute();
final JsonNode root = this.om.readTree(response.getContent());
final JsonNode results = root.get("d").get("results");
final Set<V> values = this.om.readValue(this.om.treeAsTokens(results), 
                                        new TypeReference<Set<V>>() {});

在这种情况下,VUserresultsArray

在我添加 Identifiable&lt;T&gt; 接口之前,这个类和其他几个类的反序列化工作正常,它们都因同样的异常而中断。

这不是abstract 类,每个方法都实现了。我想我已经把@JsonIgnore 放在了我能应用的任何地方。

我仍然遇到该异常,不知道如何解决。

我感觉@JsonTypeInfo 注释中的某些内容可能会解决此问题,但示例和 javadoc 并不是为不知道何时或如何使用该注释的人编写的。

我错过了什么?

【问题讨论】:

  • 制作idtransient?
  • 没有实际的id 成员变量,它只是一个method 来返回被视为程序另一部分的id 的东西。 ID&lt;String&gt; 在某些情况下,ID&lt;Integer&gt; 在其他情况下。我更改了示例以显示这种情况。
  • V,实际上是extends Identifiable&lt;Something&gt; 的类型变量吗?在某些呼叫站点上绑定到User?在这种情况下,TypeReference 实际上无法捕获User。类型标记 hack 捕获源代码中的实际类型,在本例中为 V,它将从中提取任何通用边界,并尽其所能使用它。请参阅this 和类似的 Gson this
  • 在这种情况下,VUser,这是一个工作版本,在 V 所在的任何地方都有 User。我对其进行了泛化以尝试并重用它,因为我需要大约十几个类来完成除了类型之外的完全相同的事情。
  • 如果我使用new TypeReference&lt;Set&lt;User&gt;&gt;(以及其他一些基本假设),您的示例可以很好地解析 JSON。如果V 是一个类型变量(一个方法的泛型类型变量或一个类'),它不会,我得到你描述的异常(原因我在之前的 cmets 中描述过)。与往常一样,minimal reproducible example 很关键 :)

标签: java jackson jackson2 jackson-databind


【解决方案1】:

您正在尝试将您的 JSON 绑定到 Identifiable 类型的对象而不是 User 类型的对象,它不起作用,因为 Identifiable 是一个接口。问题不在于注释,而在于您正在执行绑定。

【讨论】:

    猜你喜欢
    • 2016-06-13
    • 1970-01-01
    • 2021-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-14
    • 2018-12-12
    • 1970-01-01
    相关资源
    最近更新 更多