Java抽象类Map的Jackson序列化问题:无法生成目标JSON格式
问题描述
目标API要求的请求JSON格式:
{ "firstName" : "XYZ", "family" : { "commonDetails" : { "secondName" : "ABC" }, "1" : "Mother name", "2" : "Father name", "3" : "Spouse name" } }
我定义的Java请求类如下:
UserDetails类
public class UserDetails { private String firstName; private Map<String, AbstractFamilyDetails> details; }
AbstractFamilyDetails抽象类
@Data @NoArgsConstructor @AllArgsConstructor @JsonIgnoreProperties("type") @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "type" ) @JsonSubTypes({ @JsonSubTypes.Type(value = FamilyCommonDetails.class, name = "COMMON_DETAILS"), @JsonSubTypes.Type(value = FamilyIndividual.class, name = "FAMILY") }) public abstract class AbstractFamilyDetails { private String type; }
FamilyCommonDetails子类
@Data @EqualsAndHashCode(callSuper = true) public class FamilyCommonDetails extends AbstractFamilyDetails { private String secondName; @Builder public FamilyCommonDetails(String secondName) { super("COMMON_DETAILS"); this.secondName = secondName; } public FamilyCommonDetails() { super("COMMON_DETAILS"); } @Override public String toString() { return this.secondName; } }
FamilyIndividual子类
@Data @EqualsAndHashCode(callSuper = true) public class FamilyIndividual extends AbstractFamilyDetails { private String individual; @Builder public FamilyIndividual(String individual) { super("FAMILY"); this.individual = individual; } public FamilyIndividual() { super("FAMILY"); } @Override public String toString() { return this.individual; } }
但实际发送给服务器的JSON是:
{ "firstName" : "XYZ", "family" : { "commonDetails" : { "secondName" : "ABC", }, "1" : {"individual": "Mother name"}, "2" : {"individual": "Father name"}, "3" : {"individual": "Spouse name"} } }
请问哪里出错了?是否需要自定义Jackson序列化器实现需求?
解决方案
问题根源
FamilyIndividual序列化方式不符合要求:Jackson默认会把对象序列化为键值对结构,所以你的FamilyIndividual实例被转成了{"individual": "xxx"}的嵌套对象,但API需要的是直接的字符串值。- 字段名映射问题:你的
UserDetails类里字段叫details,但目标JSON里对应的键是family(看你实际输出已经是family,应该是已经补了@JsonProperty,但这里还是提一下避免遗漏)。
解决步骤
不需要写复杂的自定义序列化器,用Jackson自带的@JsonValue注解就能解决核心问题:
1. 修改FamilyIndividual类
给individual字段加上@JsonValue注解,告诉Jackson直接序列化这个字段的字符串值,而不是整个对象:
@Data @EqualsAndHashCode(callSuper = true) public class FamilyIndividual extends AbstractFamilyDetails { @JsonValue private String individual; @Builder public FamilyIndividual(String individual) { super("FAMILY"); this.individual = individual; } public FamilyIndividual() { super("FAMILY"); } @Override public String toString() { return this.individual; } }
2. 修正字段名映射(如果没做的话)
给UserDetails的details字段加上@JsonProperty("family"),确保序列化后的键名符合API要求:
public class UserDetails { private String firstName; @JsonProperty("family") private Map<String, AbstractFamilyDetails> details; }
验证效果
修改后生成的JSON会完全匹配API要求的格式:
{ "firstName" : "XYZ", "family" : { "commonDetails" : { "secondName" : "ABC" }, "1" : "Mother name", "2" : "Father name", "3" : "Spouse name" } }
内容的提问来源于stack exchange,提问作者kgsd
相关产品推荐
相关产品推荐

