Spring Boot自引用分类对象序列化无方括号嵌套JSON问题
嵌套分类对象自定义JSON序列化解决方案
方案1:保留原有Category实体类,自定义Jackson序列化器
第一步:编写自定义序列化类
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; import com.fasterxml.jackson.databind.node.ObjectNode; import java.io.IOException; public class CategorySerializer extends StdSerializer<Category> { public CategorySerializer() { super(Category.class); } @Override public void serialize(Category category, JsonGenerator gen, SerializerProvider provider) throws IOException { gen.writeStartObject(); // 以当前分类名称为键 gen.writeFieldName(category.getName()); // 写入子分类嵌套对象 gen.writeObject(buildSubNode(category, provider)); gen.writeEndObject(); } // 递归构造子分类的嵌套对象 private ObjectNode buildSubNode(Category category, SerializerProvider provider) { ObjectNode node = provider.getNodeFactory().objectNode(); if (category.getSubCategory() != null && !category.getSubCategory().isEmpty()) { for (Category sub : category.getSubCategory()) { node.set(sub.getName(), buildSubNode(sub, provider)); } } return node; } }
第二步:绑定序列化器到Category类
两种绑定方式二选一:
- 直接在Category类上加注解:
import com.fasterxml.jackson.databind.annotation.JsonSerialize; @JsonSerialize(using = CategorySerializer.class) public class Category { private String name; private List<Category> subCategory; // 原有getter、setter、构造方法保持不变 }
- 手动注册到ObjectMapper(不需要修改实体类):
ObjectMapper mapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); module.addSerializer(Category.class, new CategorySerializer()); mapper.registerModule(module); mapper.enable(SerializationFeature.INDENT_OUTPUT);
修改完成后运行你原有测试代码,即可输出期望的JSON格式。
方案2:调整Map构造逻辑,不使用MultiValuedMap
你之前用MultiValuedMap导致同一个key对应的值被序列化为数组,直接用普通HashMap构造嵌套结构即可:
@Test public void testCategory2() throws JsonProcessingException { // 构造英国下面的城市节点 Map<String, Object> ukSub = new HashMap<>(); ukSub.put("London", new HashMap<>()); ukSub.put("Leeds", new HashMap<>()); // 构造欧洲节点 Map<String, Object> europe = Map.of("Europe", Map.of("UK", ukSub)); ObjectMapper mapper = new ObjectMapper(); mapper.enable(SerializationFeature.INDENT_OUTPUT); String json = mapper.writeValueAsString(europe); System.out.println(json); }
运行后输出完全符合你的预期。
内容的提问来源于stack exchange,提问作者Ian McGrath
相关产品推荐
相关产品推荐

