You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用ReloadableConfiguration读取JSON配置时Map属性返回Null问题

解决Apache Commons Configuration读取JSON嵌套Map返回null的问题

问题根源

当前实现存在两个核心问题:

  1. 构建JSONConfiguration时使用了通用的fileBased()参数配置,未启用JSON专属解析规则,导致嵌套对象无法被正确识别
  2. 自定义的ReloadableConfiguration可能未正确委托底层配置的属性获取逻辑,或者未触发配置重载检查

具体修复步骤

1. 修改ConfigurationBuilder的配置参数

将通用的fileBased()替换为JSON专属的json()配置,确保JSON解析器正确处理嵌套对象:

ReloadingFileBasedConfigurationBuilder<FileBasedConfiguration> builder = 
        new ReloadingFileBasedConfigurationBuilder<>(JSONConfiguration.class)
        .configure(
                params.json()
                        .setFile(configurationFile.toFile())
                        .setAllowNestedKeys(true) // 显式开启嵌套键支持,默认已启用但显式设置更稳妥
        );

2. 检查ReloadableConfiguration的实现

确保ReloadableConfiguration类正确代理底层配置的方法,并且在获取属性前触发重载检查:

public class ReloadableConfiguration implements ImmutableConfiguration {
    private final ReloadingFileBasedConfigurationBuilder<FileBasedConfiguration> builder;

    public ReloadableConfiguration(ReloadingFileBasedConfigurationBuilder<FileBasedConfiguration> builder) {
        this.builder = builder;
    }

    @Override
    public Object getProperty(String key) {
        try {
            // 先检查配置是否需要重载
            builder.getReloadingController().checkForReloading(null);
            // 委托给底层的JSONConfiguration获取属性
            return builder.getConfiguration().getProperty(key);
        } catch (ConfigurationException e) {
            throw new RuntimeException("Failed to get configuration property", e);
        }
    }

    // 实现其他ImmutableConfiguration方法时,同样要先检查重载再委托
    @Override
    public <T> T get(String key, Class<T> type) {
        try {
            builder.getReloadingController().checkForReloading(null);
            return builder.getConfiguration().get(key, type);
        } catch (ConfigurationException e) {
            throw new RuntimeException(e);
        }
    }

    // 示例:直接获取Map的方法
    @SuppressWarnings("unchecked")
    public Map<String, String> getMap(String key) {
        return (Map<String, String>) getProperty(key);
    }
}

3. 优化测试用例中的Map获取逻辑

直接使用getMap方法或者get方法指定类型,避免手动序列化转换:

// 测试map
Map<String, String> foo = configuration.getMap("foo");
assertNotNull(foo);
Map<String, String> map1 = Stream.of(new String[][] {
        { "k1", "A" },
        { "k2", "B" },
}).collect(Collectors.toMap(data -> data[0], data -> data[1]));
assertEquals(map1, foo);

额外说明

Apache Commons Configuration的JSONConfiguration默认会将嵌套JSON对象解析为HierarchicalConfiguration实例,但getMap方法会自动将其转换为Map类型。如果直接用getProperty获取,也可以手动转换:

HierarchicalConfiguration config = (HierarchicalConfiguration) configuration.getProperty("foo");
Map<String, String> fooMap = config.getMap(String.class);

内容的提问来源于stack exchange,提问作者AnnetteC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 14:23:10