Spring Boot中Jackson Mapper继承场景下的序列化字段排序问题
解决Jackson继承场景下属性序列化顺序问题
问题分析
你遇到的核心问题是:Jackson默认会优先序列化父类属性,再处理子类属性,即使给父类非id属性设置了高值的@JsonProperty(index),也无法让子类属性插入到id和父类其他属性之间——这是因为旧版Jackson(2.3及以下)的index仅在同一类的属性间生效,跨类时父类属性的处理优先级更高;新版Jackson中未指定index的子类属性默认会排在所有带index的属性之后,同样不符合需求。
解决方案
方案1:自定义全局属性排序策略(推荐,无需修改子类)
通过实现Jackson的BeanPropertyOrderingStrategy,全局定义排序规则,所有继承BaseEntity的子类自动生效:
- 实现自定义排序策略类
import com.fasterxml.jackson.databind.SerializationConfig; import com.fasterxml.jackson.databind.ser.BeanPropertyWriter; import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyOrderingStrategy; import java.util.ArrayList; import java.util.List; public class BaseEntityPropertyOrderStrategy extends SimpleBeanPropertyOrderingStrategy { @Override public List<BeanPropertyWriter> orderProperties(SerializationConfig config, List<BeanPropertyWriter> props) { List<BeanPropertyWriter> orderedProps = new ArrayList<>(); List<BeanPropertyWriter> subclassProps = new ArrayList<>(); List<BeanPropertyWriter> baseAuditProps = new ArrayList<>(); // 按规则分类属性 for (BeanPropertyWriter prop : props) { String propName = prop.getName(); if ("id".equals(propName)) { orderedProps.add(prop); // id放在最前面 } else if (isBaseAuditProperty(propName)) { baseAuditProps.add(prop); // 父类审计属性归类 } else { subclassProps.add(prop); // 子类自定义属性归类 } } // 拼接最终顺序:id -> 子类属性 -> 父类审计属性 orderedProps.addAll(subclassProps); orderedProps.addAll(baseAuditProps); return orderedProps; } // 定义父类需要后置的属性 private boolean isBaseAuditProperty(String propName) { return "creationDate".equals(propName) || "modificationDate".equals(propName) || "creationUser".equals(propName) || "modificationUser".equals(propName); } }
- 注册到ObjectMapper(Spring Boot项目示例)
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.fasterxml.jackson.databind.ObjectMapper; @Configuration public class JacksonConfig { @Bean public ObjectMapper objectMapper() { ObjectMapper mapper = new ObjectMapper(); // 启用自定义排序策略 mapper.setPropertyOrderingStrategy(new BaseEntityPropertyOrderStrategy()); return mapper; } }
方案2:新版Jackson跨类index配置(需给子类属性加注解)
如果使用Jackson 2.4+版本,可通过精准设置index值实现顺序,但需要给子类属性添加注解:
- 父类
BaseEntity的id字段:@JsonProperty(index = 1) - 父类审计属性(creationDate等):
@JsonProperty(index = 100) - 子类属性(如name、sex):分别设置
@JsonProperty(index = 2)、@JsonProperty(index = 3)(值介于1和100之间)
此方法需要修改每个子类的属性注解,适合子类数量较少的场景。
内容的提问来源于stack exchange,提问作者user2087103
相关产品推荐
相关产品推荐

