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

Spring Boot 3.2中YamlPropertySourceFactory加载特殊字符键丢失问题

问题:Spring Boot加载YAML含特殊字符的键丢失特殊字符

使用Spring Boot 3.2 + Java 21 + SnakeYAML 2.2加载sources.yaml时,发现键"S&P"被加载为"SP",其他含特殊字符的键也存在特殊字符丢失情况。调试发现文件初始加载正确,但后续处理中出现异常。

原因分析

问题出在自定义的YamlPropertySourceFactory中:将YAML内容转换为Properties对象后,再通过PropertiesPropertySource返回。而Properties类基于传统.properties文件格式设计,会自动处理键中的特殊字符(比如&会被视为转义标记或直接忽略),导致原始YAML键中的特殊字符丢失。

解决方案

不要将YAML转换为Properties,而是直接加载YAML为Map,使用MapPropertySource作为属性源,避免Properties对键的特殊处理。

修改后的YamlPropertySourceFactory代码

import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;
import org.springframework.yaml.snakeyaml.Yaml;

import java.io.IOException;
import java.util.Map;
import java.util.Objects;

public class YamlPropertySourceFactory implements PropertySourceFactory {

    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource encodedResource) throws IOException {
        Yaml yaml = new Yaml();
        Map<String, Object> yamlMap = yaml.load(encodedResource.getResource().getInputStream());
        
        String fileName = encodedResource.getResource().getFilename();
        Objects.requireNonNull(fileName);
        Objects.requireNonNull(yamlMap);
        
        return new MapPropertySource(fileName, yamlMap);
    }
}

更简洁的原生方案:Spring Boot内置支持

Spring Boot 3.x支持直接通过@ConfigurationProperties加载外部YAML文件,无需自定义PropertySourceFactory,可简化配置:

  1. 修改SourcesConfig2类,移除@PropertySource注解:
@Configuration
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "sources")
@Slf4j
public class SourcesConfig2 {

    @Getter
    @Setter
    private Map<String, MetaData> sources;

    @Data
    public static class MetaData {
        private String cron;
        private boolean calculateCA;
        private boolean modifyOhlc;
        private String lastUpdatedTime;
        private ZoneOffset gmtOffset;
    }
}
  1. 在application.properties或application.yaml中指定外部配置文件导入:
spring.config.import=file:config/sources.yml

Spring Boot会直接加载外部sources.yml,并完整保留键中的特殊字符。

验证

修改后重启应用,检查sources映射中的键,"S&P"会被正确保留,不会丢失特殊字符。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 21:28:23