我有许多类要序列化为 JSON。它们非常相似,所以我想知道是否有比每次出现这种模式时创建 3 个非常接近相同的类更好的方法:

public class SomethingFoo {
  @JsonProperty("foo")
  Identifier foo

  // other properties
}

public class SomethingBar {
  @JsonProperty("bar")
  Identifier bar

  // other properties
}

public class SomethingBaz {
  @JsonProperty("baz")
  Identifier baz

  // other properties
}

标识符是一个只包含一个字段的类:
public class Identifier {
  @JsonProperty("name")
  String name = "";
}

我想做的是将标识符更改为:
public class Identifier {
  @JsonProperty("name")
  String name = "";

  @JsonIgnore
  IdentifierType type;
}

public Enum IdentifierType {
  FOO, BAR, BAZ;
}

然后我想使用标识符中的“类型”字段来更改包含这些标识符的对象中标识符字段的名称。

然后我想用这个替换SomethingFoo、SomethingBar和SomethingBaz:
public class Something {
  @JsonProperty(??????)
  Identifier name

  // other properties
}

我希望Something.identifier 的属性名称为“foo”、“bar”或“baz”,具体取决于Identifier.type 的值。

或者,我也可以子类标识符,而不是使用枚举。

问题是我试图使用对象中的值(或对象的类型,如果使用子类)来通知标识符包含类中的属性名称。所以我不知道在不更改每个包含标识符的类的情况下我想要做什么甚至是可能的。

编辑:

问题是我希望将“Something”序列化为其中之一(基于标识符的枚举类型(或子类,如果这是实现此目的的更好方法)):
{
  "foo" : {
     "name" : "blahblahblah"
  }
}

{
  "bar" : {
     "name" : "blahblahblah"
  }
}

{
  "baz" : {
     "name" : "blahblahblah"
  }
}

最佳答案

Annotations 的属性值必须是常量,因此您无法更改它。我不确定我在这里看到了问题。为什么你下面的解决方案不起作用? @JsonProperty 只是告诉 ObjectMapper Json 字段的名称应该是什么。

public class Something {
  @JsonProperty(value = "id")
  Identifier identifier

  // other properties
}

如果您序列化这些对象之一,它会得到这样的结果:
{
  "id": FOO,
  ...
}

如果没有 value - "id"@JsonProperty ,它只会使用字段名称:
{
  "identifier": FOO,
  ...
}

Jackson 有很多方法可以自定义它序列化和反序列化对象。如果您希望序列化具有更多信息(例如,如果您向 Enum 添加任何字段)或想要更改它的序列化方式,则有一些方法可以做到这一点。例如,如果您希望将 Enum 序列化为一个对象在 Jackson 2.1.2 @JsonFormat 中,您可以执行以下操作:
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum Identifier {...}

编辑:
我认为将数据序列化为上述格式不一定有意义,因为您实际上不再将对象表示为 JSON,而是将其表示为不同的对象。您已经在对象上有一个字段来区分该对象的 Identifier 是什么,您可以在其他任何地方使用它。如果您真的想将数据序列化为上述方式,我相信您必须为该类型实现自己的 JsonSerializer 像这样(至少对于 Jackson 2.1):
public SomethingSerializer extends JsonSerializer<Something> {
  // Define serialization methods
  ...
}

然后扩展 SimpleModule,添加序列化器,并使用 ObjectMapper 注册模块:
ObjectMapper mapper = new ObjectMapper();
SimpleModule testModule = new SimpleModule("MyModule", new Version(1, 0, 0, null));
testModule.addSerializer(new SomethingSerializer());
mapper.registerModule(testModule);

示例改编自 JacksonHowToCustomSerializers

关于java - Jackson 序列化的动态属性名称,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25877741/

10-11 22:20
查看更多