java - 当使用“-”连字符或“_”下划线时,Spring Boot 从 YAML 配置中为映射加载错误的键值对
问题描述
我正在使用自定义的“YamlPropertySourceFactory”在 Spring Boot 中加载 yaml 配置。当配置作为 Map 加载时,它会为下面的场景加载错误的键值对值。
SpringBoot 'PropertySourceFactory' 假定键值'CORE_3_1' 和 'CORE_31' OR 'CORE-3-1' 和 'CORE-31' 相同。
- 实际输出:{CORE_31=31, CORE_32=32, CORE_3_1=31 }
- 预期输出:{CORE_31=31, CORE_32=32, CORE_3_1=30 }
以下是复制此问题的示例代码。
Yaml 配置- response-mapping.yaml
mappings:
response-code:
mappings:
CORE_3_1: "30"
CORE_31: "31"
CORE_32: "32"
或者
Yaml 配置- response-mapping.yaml
mappings:
response-code:
mappings:
CORE-3-1: "30"
CORE-31: "31"
CORE-32: "32"
自定义 YamlPropertySourceFactory
import java.util.Properties;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;
public final class YamlPropertySourceFactory implements PropertySourceFactory {
@Override
public PropertiesPropertySource createPropertySource(@SuppressWarnings("unused") final String name, final EncodedResource encodedResource) {
final YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(encodedResource.getResource());
final Properties properties = factory.getObject();
return new PropertiesPropertySource(encodedResource.getResource().getFilename(), properties);
}
}
响应配置类
import java.util.Map;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
/**
* It is used to load response codes from YAML configuration.
*/
@Configuration
@ConfigurationProperties(prefix = "mappings.response-code")
@PropertySource(value = "classpath:response-mapping.yaml", factory = YamlPropertySourceFactory.class)
public class ResponseCode {
private Map<String, String> mappings;
public Map<String, String> getMappings() {
return this.mappings;
}
public String getMapping( final String errorCode) {
return this.mappings.get(errorCode);
}
public void setMappings(final Map<String, String> value) {
this.mappings = value;
}
@Override
public String toString() {
return "ResponseCode{" + "mappings=" + this.mappings + '}';
}
}
简单的控制器来测试它。- http://localhost:8080/代码
package de.fiserv.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoController {
@Autowired
private ResponseCode responseCode;
@GetMapping(value = "/code")
public ResponseEntity<String> code() {
return new ResponseEntity<>(this.responseCode.getMappings().toString(), HttpStatus.OK);
}
}
我找到了解决方法,将 '-' OR '_' 替换为 '.' 关键,它可以工作,但它会破坏错误代码映射的整个设计。
解决方案
更新了 Yaml 配置- response-mapping.yaml
mappings:
response-code:
mappings:
"[CORE_3_1]": "30"
CORE_31: "31"
为什么会这样?
Spring Boot 使用一些宽松的规则将 Environment 属性绑定到 @ConfigurationProperties bean,因此 Environment 属性名称和 bean 属性名称之间不需要完全匹配。这很有用的常见示例包括破折号分隔的环境属性(例如,上下文路径绑定到 contextPath)和大写环境属性(例如,PORT 绑定到端口)。
推荐阅读
- ruby-on-rails - 如何在 rails 5 的 to_csv 方法中添加指向单个记录的链接,以便在 csv 导出中打印绝对 url?
- asp.net - 在 Angular/MVC 架构中处理会话
- python - 表 python 中的输出
- windows - exec-maven-plugin 无法在 Windows 机器上运行“mvn”命令
- python - 追加到一个嵌套列表追加到所有嵌套列表
- javascript - 函数调用中的字符串与函数中定义的字符串不同 - 奇怪的错误
- c# - 运行 URL 并获取新链接
- docker-compose - traefik docker-compose 容器交叉通信
- c# - 实体框架 - 似乎无法加载相关实体
- python - Python - 如何添加输入错误消息