Controller返回VO时不修改原有数据结构如何自定义JSON输出格式?
Java后端VO序列化自定义字段名和结构方案
SpringBoot默认使用Jackson作为JSON序列化框架,无需修改原有RailVO的List<RobotVO>类型字段结构,通过Jackson注解+自定义序列化器即可实现需求。
注意:你给出的期望JSON存在格式笔误,带字符串键的键值对结构属于JSON对象,需用
{}包裹而非数组的[],最终返回的合法rbtInfo为对象结构。
实现步骤
给RailVO的对应字段添加Jackson注解
给robotVO字段添加@JsonProperty指定序列化后的字段名,添加@JsonSerialize指定自定义序列化器处理该List字段的序列化逻辑,原有getter/setter、字段类型完全不需要改动:public class RailVO { private String railLength; private String railDesc; // 仅添加两个注解即可 @JsonProperty("rbtInfo") @JsonSerialize(using = RobotListSerializer.class) private List<RobotVO> robotVO; // 原有getter、setter保持不变 public List<RobotVO> getRobotVO() { return robotVO; } public void setRobotVO(List<RobotVO> robotVO) { this.robotVO = robotVO; } // 其他字段的getter、setter省略 }编写List
的自定义序列化器
该序列化器会将List序列化为带R01、R02格式键的JSON对象:import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; import java.io.IOException; import java.util.List; public class RobotListSerializer extends StdSerializer<List<RobotVO>> { // 无参构造器 public RobotListSerializer() { super((Class) List.class); } @Override public void serialize(List<RobotVO> robotList, JsonGenerator gen, SerializerProvider provider) throws IOException { // 开始写入JSON对象 gen.writeStartObject(); for (int i = 0; i < robotList.size(); i++) { // 生成R01、R02格式的键,不足两位补0 String key = String.format("R%02d", i + 1); gen.writeObjectField(key, robotList.get(i)); } // 结束写入JSON对象 gen.writeEndObject(); } }其他调整
- 你示例的Controller代码存在对象引用复用的BUG:仅实例化了一个RobotVO对象,多次set属性后加入List,最终List中所有元素都会被覆盖为最后一次设置的值,需要每次添加前新建RobotVO实例:
List<RobotVO> robotList = new ArrayList<RobotVO>(); // 每次添加都新建对象 RobotVO robot1 = new RobotVO(); robot1.setStationPosition("21300"); robot1.setStartPosition("0"); robot1.setEndPosition("30000"); robotList.add(robot1); RobotVO robot2 = new RobotVO(); robot2.setStationPosition("51300"); robot2.setStartPosition("30000"); robot2.setEndPosition("60000"); robotList.add(robot2); RobotVO robot3 = new RobotVO(); robot3.setStationPosition("81300"); robot3.setStartPosition("60000"); robot3.setEndPosition("91300"); robotList.add(robot3); rail.setRobotVO(robotList); railDesc字段直接在Controller业务逻辑中设置为你期望的字符串即可:rail.setRailDesc("Rails patrolling by robots 1, 2, 3, guard post ~ xx")
- 你示例的Controller代码存在对象引用复用的BUG:仅实例化了一个RobotVO对象,多次set属性后加入List,最终List中所有元素都会被覆盖为最后一次设置的值,需要每次添加前新建RobotVO实例:
内容的提问来源于stack exchange,提问作者ringhiosi
相关产品推荐
相关产品推荐

