Java使用BasicDynaBean接收Postgres查询结果返回嵌套空行如何解决
问题根因与解决方案
问题根因
无限嵌套问题是Jackson序列化BasicDynaBean对象时的循环引用导致的。BasicDynaBean内置了dynaClass属性,而dynaClass中又包含了所有行数据的rows集合,每个rows元素又是BasicDynaBean类型,序列化时就会进入「序列化Bean→序列化dynaClass→序列化rows→序列化每个Bean的dynaClass」的无限循环。
另外你的代码还存在一个小笔误:创建了response对象并放入result后,返回的是result而不是response,如果接口期望返回的是包含result字段的结构体,记得修正返回值为response。
可落地解决方法
方案1:将BasicDynaBean转换为普通Map集合(最稳妥无副作用)
直接遍历BasicDynaBean列表,把每个对象的属性提取为普通HashMap,完全规避DynaBean自带的特殊字段序列化问题。示例代码:
// 转换工具代码 List<Map<String, Object>> plainResult = result.stream().map(bean -> { Map<String, Object> map = new HashMap<>(); DynaClass dynaClass = bean.getDynaClass(); for (DynaProperty prop : dynaClass.getDynaProperties()) { String propName = prop.getName(); map.put(propName, bean.get(propName)); } return map; }).collect(Collectors.toList()); // 放入响应返回 response.put("result", plainResult); return response;
方案2:配置Jackson忽略dynaClass字段
如果要保留BasicDynaBean类型不转换,可以全局配置Jackson序列化时忽略BasicDynaBean的dynaClass字段,避免循环。可以在Spring Boot配置类中添加如下配置:
import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.beanutils.BasicDynaBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; @Configuration public class JacksonConfig { @Bean public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) { ObjectMapper objectMapper = builder.createXmlMapper(false).build(); // 为BasicDynaBean添加忽略dynaClass字段的注解配置 objectMapper.addMixIn(BasicDynaBean.class, IgnoreDynaClass.class); return objectMapper; } // 混合注解类,用于指定忽略字段 abstract class IgnoreDynaClass { @com.fasterxml.jackson.annotation.JsonIgnore abstract org.apache.commons.beanutils.DynaClass getDynaClass(); } }
方案3:直接使用Spring自带的Map结果映射(从根源规避问题)
如果没有必须使用BasicDynaBean的特殊需求,可以直接替换RowToBasicDynaBeanMapper,使用Spring JDBC自带的结果映射直接返回Map列表:
// 直接用queryForList获取普通Map集合,不需要自定义Mapper String query="SELECT * FROM students"; List<Map<String, Object>> result = jdbcTemplate.queryForList(query, parameters); response.put("result",result); return response;
内容的提问来源于stack exchange,提问作者rudeTool
相关产品推荐
相关产品推荐

