简体   繁体   English

当使用“-”连字符或“_”下划线时,Spring Boot 从 YAML 配置加载错误的键值对映射

[英]Spring Boot Loads wrong key-value pair for map from YAML configureation when '-' hyphen OR '_' underscore is used

I am using custom 'YamlPropertySourceFactory' to load yaml configuration in Spring boot.我正在使用自定义的“YamlPropertySourceFactory”在 Spring Boot 中加载 yaml 配置。 When configs are loaded as Map it loads wrong key-value pair value for below scenerio.当配置作为 Map 加载时,它会为下面的场景加载错误的键值对值。

SpringBoot 'PropertySourceFactory' assumes value of keys'CORE_3_1' and 'CORE_31' OR 'CORE-3-1' and 'CORE-31'same. SpringBoot 'PropertySourceFactory' 假定键值 'CORE_3_1' 和 'CORE_31' OR 'CORE-3-1' 和 'CORE-31' 相同。

  • Actual Output: {CORE_31=31, CORE_32=32, CORE_3_1=31 }实际输出:{CORE_31=31, CORE_32=32, CORE_3_1=31 }
  • Expected Output: {CORE_31=31, CORE_32=32, CORE_3_1=30 }预期输出:{CORE_31=31, CORE_32=32, CORE_3_1=30 }

Below is the sample code to replicate this issue.下面是复制此问题的示例代码。

Yaml Config - response-mapping.yaml Yaml 配置- response-mapping.yaml

mappings:
  response-code:
    mappings:
      CORE_3_1: "30"
      CORE_31: "31"
      CORE_32: "32"

OR或者

Yaml Config - response-mapping.yaml Yaml 配置- response-mapping.yaml

mappings:
  response-code:
    mappings:
      CORE-3-1: "30"
      CORE-31: "31"
      CORE-32: "32"

Custom YamlPropertySourceFactory自定义 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);
    }
}

Response Config Class响应配置类

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 + '}';
    }
}

Simple Controller to test it.简单的控制器来测试它。 - http://localhost:8080/code - http://localhost:8080/code

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);
    }

}

I have found the workaround by replacing '-' OR '_' with '.'我找到了解决方法,将 '-' OR '_' 替换为 '.' in key and it works but it would break whole design of error code mapping.在 key 中它可以工作,但它会破坏错误代码映射的整个设计。

Reference: https://www.baeldung.com/spring-yaml-propertysource参考: https : //www.baeldung.com/spring-yaml-propertysource

Found Solution at: https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.external-config.typesafe-configuration-properties.relaxed-binding.environment-variables在以下位置找到解决方案: https : //docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.external-config.typesafe-configuration-properties.relaxed-binding.environment-variables

Updated Yaml Config - response-mapping.yaml更新的 Yaml 配置- response-mapping.yaml

mappings:
  response-code:
    mappings:
      "[CORE_3_1]": "30"
      CORE_31: "31"

Why this was happening?为什么会这样?

Spring Boot uses some relaxed rules for binding Environment properties to @ConfigurationProperties beans, so there does not need to be an exact match between the Environment property name and the bean property name. Spring Boot 使用一些宽松的规则将 Environment 属性绑定到 @ConfigurationProperties bean,因此 Environment 属性名称和 bean 属性名称之间不需要完全匹配。 Common examples where this is useful include dash-separated environment properties (for example, context-path binds to contextPath), and capitalized environment properties (for example, PORT binds to port).这很有用的常见示例包括以破折号分隔的环境属性(例如,上下文路径绑定到上下文路径)和大写的环境属性(例如,端口绑定到端口)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM