Spring Boot中Jackson序列化对象出现额外重复字段问题
Jackson序列化出现重复字段的解决方案
问题原因
你遇到的重复字段(如student_uid与studentUID、requirement_id与requirementID)是因为Jackson同时处理了实体类的字段本身和对应的getter/setter方法:
- 下划线风格的键名来自字段的原始命名;
- 驼峰风格的键名来自getter方法的命名(JavaBean规范下,
getStudent()会被Jackson默认转换为studentUID,getRequirementId()会转换为requirementID)。
即使你给部分字段加了@JsonProperty指定下划线键名,Jackson依然会解析getter方法生成额外的驼峰键名,导致重复。
解决方案
1. 统一Jackson命名策略(推荐)
配置Jackson全局使用下划线命名策略,让字段和getter方法的命名统一转换为下划线风格,避免重复。
方式A:Spring Boot配置文件
在application.properties中添加:
spring.jackson.property-naming-strategy=SNAKE_CASE
或application.yml:
spring: jackson: property-naming-strategy: SNAKE_CASE
方式B:局部配置ObjectMapper
如果只需要在当前接口生效,修改序列化代码:
@RequestMapping(path = "/student/requirements/{uid}") public String getStudentRequirements(@PathVariable String uid) throws JsonProcessingException { List<RequirementInstance> requirements = instance_repo.findByStudent(uid); if(requirements != null) { ObjectMapper mapper = new ObjectMapper(); mapper.enable(SerializationFeature.INDENT_OUTPUT); // 设置下划线命名策略 mapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE); // 直接序列化List即可,无需转数组 return mapper.writeValueAsString(requirements); } return "{\"error\": \"Unable to locate user with UID of " + uid + ".\"}"; }
2. 限制Jackson只序列化字段
在实体类RequirementInstance上添加@JsonAutoDetect注解,指定只处理字段,忽略getter/setter方法:
@Entity @JsonAutoDetect( fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.NONE ) public class RequirementInstance { @Id @GeneratedValue(strategy = GenerationType.AUTO) private int id; private int requirement_id; @JsonProperty("student_uid") private String student; private String status; @Nullable @JsonProperty("doc_guid") private String doc_guid; @Nullable @JsonProperty("retake_date") private Date retake_date; // 你的getter/setter方法... }
3. 局部字段添加@JsonIgnore
针对个别字段,在对应的getter方法上添加@JsonIgnore,让Jackson忽略该getter生成的键名:
@JsonProperty("student_uid") private String student; // 忽略该getter,避免生成studentUID字段 @JsonIgnore public String getStudent() { return student; }
内容的提问来源于stack exchange,提问作者sammyg7241
相关产品推荐
相关产品推荐

