调用REST服务URI返回JSON出现重复字段(Name、Roll)问题咨询
为什么返回的JSON里Name/name、Roll/roll会重复?
先看你提供的代码:
package Book; import java.util.ArrayList; import java.util.List; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; @Path("/resrtest") public class Test { @GET @Produces({MediaType.APPLICATION_JSON}) public Student datareturn() { Student student = new Student(); student.setName("ram"); student.setAge(29); student.setSection("A"); student.setRoll(11); student.setFathername("sam"); student.setSchoolname("ANC"); return student; } }
输出的JSON是:
{"Name":"ram","Roll":11,"age":29,"fathername":"sam","name":"ram","roll":11,"schoolname":"ANC","section":"A"}
这个问题的核心是JSON序列化器同时处理了类的成员字段和getter方法,导致同一个属性被序列化了两次:
背后的原因
虽然你没贴Student类的代码,但从setName、setRoll这些方法能推断,你的Student类大概是这样的:
public class Student { // 成员字段 private String name; private int roll; private int age; // 其他字段... // getter/setter public String getName() { return name; } public void setName(String name) { this.name = name; } public int getRoll() { return roll; } public void setRoll(int roll) { this.roll = roll; } // 其他getter/setter... }
你用的JAX-RS默认JSON序列化器(比如Jackson早期版本、或者基于JAXB的序列化)会做两件事:
- 直接序列化类的私有成员字段(比如
name、roll),生成小写的键 - 解析getter方法名称:把
getName()去掉get后首字母大写,得到Name;getRoll()得到Roll,生成大写开头的键
两者叠加,就出现了同一个属性重复的情况。
怎么修复?
给你几个实用的解决方案:
方案1:用Jackson注解指定序列化规则
如果你的项目用Jackson做JSON序列化,可以给Student类加@JsonAutoDetect注解,指定只序列化字段(或者只序列化getter),避免重复:
import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; @JsonAutoDetect( fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE ) public class Student { // 原类内容不变 }
这样序列化器只会处理成员字段,不会解析getter方法,就不会有重复键了。
方案2:统一序列化策略
配置序列化器只识别getter方法(这是更常见的做法),同时确保成员字段是私有且不被直接序列化。比如用Jackson的话,给字段加@JsonIgnore注解,让序列化器忽略字段,只处理getter:
import com.fasterxml.jackson.annotation.JsonIgnore; public class Student { @JsonIgnore private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } // 其他字段同理... }
方案3:用JAXB注解规范字段名
如果你的项目用JAXB做序列化,可以在getter方法上添加@XmlElement注解,指定统一的字段名,同时避免重复:
import javax.xml.bind.annotation.XmlElement; public class Student { private String name; @XmlElement(name = "name") public String getName() { return name; } public void setName(String name) { this.name = name; } // 其他字段同理... }
内容的提问来源于stack exchange,提问作者DAWN
相关产品推荐
相关产品推荐

