如何在Spring Boot中定义并读取Map<List<String>, List<String>>类型YML配置
Spring Boot 读取 Map<List, List> 类型配置的正确方式
你原有的YAML配置无法读取的核心原因是:YAML不支持直接将列表作为Map的键,你写的['AB', 'BC', 'DD']会被解析成字符串类型的键,而非List<String>,导致Spring无法完成类型绑定。
以下两种方案可以解决这个问题:
方案一:调整YAML结构,通过中间对象转换(推荐)
这种方式无需自定义转换器,结构清晰且无字符限制,是最稳妥的实现方式。
1. 修改YAML配置
将原有的Map结构改成列表嵌套键值对的形式:
user: types: - key: ['AB', 'BC', 'DD'] value: ['Admin', 'Test'] - key: ['RR', 'TT'] value: ['Admin'] - key: ['FF'] value: ['User']
2. 调整配置类
新增一个内部类封装键值对,在set方法中将列表转换为目标Map:
@Configuration @EnableConfigurationProperties public class UserMapper { private Map<List<String>, List<String>> userMap; public Map<List<String>, List<String>> getUserMap() { return userMap; } @ConfigurationProperties("user.types") public void setTypeEntries(List<TypeEntry> typeEntries) { this.userMap = typeEntries.stream() .collect(Collectors.toMap(TypeEntry::getKey, TypeEntry::getValue)); } // 内部类用于绑定YAML中的键值对 public static class TypeEntry { private List<String> key; private List<String> value; // Getter和Setter public List<String> getKey() { return key; } public void setKey(List<String> key) { this.key = key; } public List<String> getValue() { return value; } public void setValue(List<String> value) { this.value = value; } } }
方案二:自定义字符串转列表转换器
如果希望保留类似原有的Map结构,可以通过自定义转换器,让Spring将字符串格式的键解析为List<String>。
1. 修改YAML配置
用逗号分隔的字符串作为Map的键:
user.types: "AB,BC,DD": ["Admin", "Test"] "RR,TT": ["Admin"] "FF": ["User"]
2. 实现自定义转换器
创建一个转换器,将逗号分隔的字符串转为List<String>:
@Component public class StringToListConverter implements Converter<String, List<String>> { @Override public List<String> convert(String source) { if (source == null || source.isBlank()) { return Collections.emptyList(); } return Arrays.asList(source.split(",")); } }
3. 保留原配置类结构
你的原配置类可以直接使用,Spring会自动应用转换器完成类型绑定:
@Configuration @EnableConfigurationProperties public class UserMapper { private Map<List<String>, List<String>> userMap; public Map<List<String>, List<String>> getUserMap() { return userMap; } @ConfigurationProperties("user.types") public void setUserMap(final Map<List<String>, List<String>> userMap) { this.userMap = userMap; } }
注意:这种方式要求键的元素中不能包含逗号,否则会解析错误,因此仅适用于元素不含分隔符的场景。
内容的提问来源于stack exchange,提问作者Remo
相关产品推荐
相关产品推荐

