Jackson序列化的动态属性名称 [英] Dynamic property name for Jackson serialization

查看:1645
本文介绍了Jackson序列化的动态属性名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有很多我正在尝试序列化为JSON的类。它们非常相似,所以我想知道是否有更好的方法来做这个,而不是每次出现这个模式时创建3个非常接近相同的类:

I have a number of classes I'm trying to serialize to JSON. They're very similar, so I'm wondering if there's a better way to do this than creating 3 very-near-identical classes each time this pattern shows up:

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
}

标识符是一个只包含一个字段的类:

Identifier is a class that only contains one field:

public class Identifier {
  @JsonProperty("name")
  String name = "";
}

我想做的是将标识符改为:

What I would like to do, is change Identifier to something like:

public class Identifier {
  @JsonProperty("name")
  String name = "";

  @JsonIgnore
  IdentifierType type;
}

public Enum IdentifierType {
  FOO, BAR, BAZ;
}

我想在标识符中使用'type'字段来更改包含这些标识符的对象中的标识符字段的名称。

I would then like to use the 'type' field, within Identifier, to change the name of the Identifier field in the objects that contain those Identifiers.

我想用这个替换SomethingFoo,SomethingBar和SomethingBaz:

I would then like to do replace SomethingFoo, SomethingBar, and SomethingBaz with this:

public class Something {
  @JsonProperty(??????)
  Identifier name

  // other properties
}

我想要Something.identifier的房产名称是foo,bar或baz,取决于Identifier.type的值。

I would like the property name of Something.identifier to be "foo", "bar", or "baz", depending on the value of Identifier.type.

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

Alternatively, I could also sub-class Identifier, rather than use an Enum.

问题是我试图在对象中使用一个值(或者如果使用子类,则使用对象的类型)通知Identifier包含的类中的属性名称。所以我不知道在不改变包含标识符的每个类的情况下我是否可以做我想做的事。

The problem is that I'm trying to use a value within an object (or the type of the object, if sub-classes are used) to inform the property name in the Identifier's containing class. So I don't know if what I want to do is even possible without changing every class that contains an Identifier.

编辑:

问题是我希望将Something序列化为其中之一(基于Identifier的枚举类型(或子类,如果这是实现此目的的更好方法)):

The problem is I want 'Something' to be Serialized as one of these (Based on Identifier's enum type (or subclass, if that's a better way to accomplish this)):

{
  "foo" : { 
     "name" : "blahblahblah"
  }
}

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

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


推荐答案

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

Attribute values for Annotations must be constant, so you cannot change that. I'm not sure I see a problem here. Why would your solution below not work? The @JsonProperty just tells the ObjectMapper what the name of the Json field should be.

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

  // other properties
}

如果你序列化了其中一个对象,它会出现这个问题:

If you serialized one of these objects it would come out to something this:

{
  "id": FOO,
  ...
}

没有值 - id for @JsonProperty 它只会使用字段名称:

Without having the value - "id" for @JsonProperty it would just use the field name:

{
  "identifier": FOO,
  ...
}

杰克逊有一系列自定义方法序列化和反序列化对象。如果您希望序列化具有更多信息(例如,如果您向Enum添加任何字段)或想要更改它的序列化方式,那么有办法实现这一点。例如,如果您希望将Enum序列化为对象在杰克逊2.1.2 @JsonFormat 你可以这样做:

Jackson has a bunch of ways to customize it serializes and deserializes object. If you want the serialization to have more information (say if you add any fields to your Enum) or want to change how it was serialized there are ways to do that.. For Example, if you wanted the Enum to be serialized as an Object in Jackson 2.1.2 @JsonFormat you could do:

@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum Identifier {...}






编辑:
我认为将数据序列化为上述格式并不一定有意义因为您将对象表示为不同的对象,所以不再将对象真正表示为JSON。您已经在对象上有一个字段,用于区分该对象的标识符,您可以在其他任何地方使用该字段。如果你真的想按照上面描述的方式将数据序列化,我相信你必须为这种类型实现你自己的 JsonSerializer (至少对于Jackson 2.1) ):


I don't think serializing the data into the format described above necessarily makes sense as you are not really representing the object as JSON anymore as you are representing it as a different object. You already have a field on the object that discriminates what the Identifier for that object is and you can use that anywhere else. If you really wanted to serialize the data into the way you have described above, I believe you would have to implement your own JsonSerializer for that type like this (at least for Jackson 2.1):

public SomethingSerializer extends JsonSerializer<Something> {
  // Define serialization methods
  ...
}

然后扩展SimpleModule,添加序列化程序,并使用ObjectMapper注册模块:

And then extend SimpleModule, add the serializer, and register the module with ObjectMapper:

ObjectMapper mapper = new ObjectMapper();
SimpleModule testModule = new SimpleModule("MyModule", new Version(1, 0, 0, null));
testModule.addSerializer(new SomethingSerializer());
mapper.registerModule(testModule);

示例改编自 JacksonHowToCustomSerializers

这篇关于Jackson序列化的动态属性名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆