委托模式下的Jackson JSON序列化

问题描述

在我的模型中,我使用某种delegation pattern。因此,我具有接口 A 和两个实现该接口的value object B C

interface A {
  int getCount()
  String getName()
}

class B implements A {
  final int count;
  final String name;

  B(int count,String name) {
    this.count = count;
    this.name = name;
  }

  int getCount() {
    return count;
  }
 
  String getName() {
    return name;
  }
}

class C implements A {
  final int value;
  final B delegate; 

  C(B delegate,int value) {
    this.delegate = delegate;
    this.value = value;
  }

  B getDelegate() { return delegate; }

  int getValue() { return value; }

  int getCount() { return delegate.getCount(); }

  String getName() { return delegate.getName(); }
}

然后我想将 C 的实例(例如new C(new B(42,"Joe"),7))序列化为

{
  "name": "Joe","count": 42,"value": 7
}

,然后我需要反序列化它。我找到了完成任务前半部分的方法,但无法反序列化此类JSON。没有自定义反序列化器,是否可以?

解决方法

是的,您可以使用自定义解串器来实现它,但是它可能更容易修复。 我认为,如果为C类字段添加setter方法,它将可以正常工作。

,

这是一个解决方案:

@JsonAutoDetect(getterVisibility = JsonAutoDetect.Visibility.NONE)
class C implements A {
  @JsonProperty
  final int value;

  @JsonUnwrapped
  @JsonProperty(access = JsonProperty.Access.READ_ONLY)
  final B delegate; 

  @ConstructorProperties({"name","count","value"});
  C(String name,int count,int value) {
    this.delegate = new B(count,name);
    this.value = value;   
  }

  C(B delegate,int value) {
    this.delegate = delegate;
    this.value = value;
  }

  B getDelegate() { return delegate; }

  int getValue() { return value; }

  int getCount() { return delegate.getCount(); }

  String getName() { return delegate.getName(); }
}

由于杰克逊的限制,有一些与特殊的构造函数和未包装属性的访问模式有关的魔术:https://github.com/FasterXML/jackson-module-kotlin/issues/106