我有一个相对复杂的对象,其中包含许多字段。我需要使用自定义序列化程序序列化其中一个字段,但需要模拟 @JsonUnwrapped
功能。
为了简单起见,我将其削减为两个字段:
public class MyClass
{
@JsonProperty("subject")
private final String subject;
@JsonSerialize(using=MySenderSerializer.class)
private final MailActor sender;
}
我的自定义序列化器类如下:
public class MySenderSerializer extends StdSerializer<MailActor>
{
public MySenderSerializer()
{
super(MailActor.class, true);
}
@Override
public void serialize(final MailActor value, final JsonGenerator gen, final SerializerProvider provider) throws IOException
{
gen.writeStringField("from_name", value.getName());
gen.writeStringField("from_email", value.getAddress());
}
}
所有这些都很好,除了输出 JSON 如下所示:
{
...
"subject": "test subject",
"sender": {
"from_name": "test from",
"from_email": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="8cf8e9fff8ccf8e9fff8a2efe3e1" rel="noreferrer noopener nofollow">[email protected]</a>"
},
...
}
我需要解开 sender
字段,以便 JSON 如下所示:
{
...
"subject": "test subject",
"from_name": "test from",
"from_email": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="384c5d4b4c784c5d4b4c165b5755" rel="noreferrer noopener nofollow">[email protected]</a>",
...
}
如果我使用标准序列化器,我可以使用 @JsonUnwrapped 注释来执行此操作,但它似乎与自定义序列化器不兼容。如何在不为 MyClass
对象编写自定义序列化器的情况下获得所需的 JSON 输出?
最佳答案
我也必须寻找@JsonUnwrapped的替代方案,因为它给我带来了一些与这个问题无关的问题。
我实现的解决方案同样适用于您的情况,使用@JsonAnyGetter。在您的 MyClass 中,忽略需要特殊序列化的属性,而是使用 JsonAnyGetter 添加它:
public class MyClass
{
@JsonProperty("subject")
private final String subject;
@JsonIgnore
private final MailActor sender;
@JsonAnyGetter
public Map<String, Object> serializeActor() {
return sender.serializeToMap();
// Of course, here you could create an empty map
// and add the properties of many different classes.
}
}
然后在 MailActor 类中实现该方法,该方法将返回一个包含您可能需要的属性的映射。
public Map<String, Object> serializeToMap() {
final Map<String, Object> properties = new ArrayMap<>();
properties.put("from_name", this.getName());
properties.put("from_email", this.getAddress());
return properties;
}
这种方式的问题是反序列化对象,因为 @JsonAnySetter 不会像上面示例中给出的那样获取带有 JSON 的映射。在你的情况下,这甚至更加困难,因为你的类(class)属性是最终的。您需要使用 @JsonCreator 来创建所有属性。大致如下:
@JsonCreator
public MyClass( Map< String, String > json ) {
if (json.containsKey("subject")) {
subject = json.get("subject");
} else {
subject = "";
}
String name, address;
if (json.containsKey("from_name")) {
name = json.get("from_name");
} else {
name = "";
}
if (json.containsKey("from_email")) {
address = json.get("from_email");
} else {
address = "";
}
sender = new MailActor(name, address);
}
自从您发布问题以来已经有一段时间了,希望这对寻求替代方案的人有所帮助。
关于java - @JsonUnwrapped 用于自定义序列化器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26959816/