如何让@ConfigurationProperties填充Map<String,Object>时保留数组结构?
问题描述
我通过Map<String, Object> data实现动态配置,代码如下:
@Configuration @ConfigurationProperties("test") @Data public class Config { private Map<String, Object> data; }
当前YAML配置示例:
test: a: a b: b c: - name: name1 - name: name2
实际得到的结果:
{ "a": "a", "b": "b", "c": { 0: { "name": "name1" }, 1: { "name": "name2" } } }
期望得到的结果:
{ "a": "a", "b": "b", "c": [ { "name": "name1" }, { "name": "name2" } ] }
如何实现预期结果?
解决方案
Spring Boot在将YAML数组绑定到Map<String, Object>的Object类型时,默认会把数组转换成以索引为键的LinkedHashMap。要让数组被解析为List,可以通过自定义配置属性绑定转换器实现:
- 创建转换器类,识别索引式Map并转换为List:
import org.springframework.boot.context.properties.ConfigurationPropertiesBinding; import org.springframework.core.convert.converter.Converter; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.List; import java.util.Map; @Component @ConfigurationPropertiesBinding public class MapToListConverter implements Converter<Map<String, Object>, Object> { @Override public Object convert(Map<String, Object> source) { // 判断当前Map是否为索引式结构(所有键都是数字字符串) boolean isIndexedMap = source.keySet().stream() .allMatch(key -> { try { Integer.parseInt(key); return true; } catch (NumberFormatException e) { return false; } }); if (isIndexedMap) { List<Object> list = new ArrayList<>(source.size()); // 按索引顺序将元素加入List for (int i = 0; i < source.size(); i++) { list.add(source.get(String.valueOf(i))); } return list; } // 非索引式Map直接返回 return source; } }
- 保持原有
Config类不变,Spring Boot会自动使用该转换器处理配置绑定,最终data中的c字段会被解析为List,符合预期结果。
内容的提问来源于stack exchange,提问作者dat pham cao hoang
相关产品推荐
相关产品推荐

