简体   繁体   English

Java 属性 - 加载到 Map <string, abstractmap.simpleentry<string, string> &gt;</string,>

[英]Java properties - Load into Map<String, AbstractMap.SimpleEntry<String, String>>

In Spring Boot project I have a Map<String, AbstractMap.SimpleEntry<String, String>> , and use it like:在 Spring 引导项目中,我有一个Map<String, AbstractMap.SimpleEntry<String, String>> ,并像这样使用它:

testData.put("key1", new AbstractMap.SimpleEntry<>("myKey1", "myValue1");
testData.put("key2", new AbstractMap.SimpleEntry<>("myKey2", "myValue2");
...

I want to put the data into a Java properties file, to be more flexible to change it without changing the code, but how to construct the data in the properties file, to map it onto the Map?我想把数据放到一个Java属性文件中,更灵活的修改它而不改变代码,但是如何在属性文件中构造数据,将map放到Z46F3EA056CAA3126B91F3F70BEEA0上呢?

I would have a class like:我会有一个 class 像:

@Component
@PropertySource("classpath:testdata.properties")
@ConfigurationProperties(prefix = "test.data")
public class TestDataProperties {
    private Map<String, AbstractMap.SimpleEntry<String, String>> testData;

    // Getter/Setter
}

When constructing in testData.properties , like:testData.properties中构建时,例如:

test.data.testData.key1=myKey1,myValue1

and using it where needed with:并在需要时使用它:

@Autowired
TestDataProperties testDataProperties;

I get Exceptions:我得到例外:

org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'test.data.testdata.key1' to java.util.AbstractMap$SimpleEntry<java.lang.String, java.lang.String>

org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [java.util.AbstractMap$SimpleEntry<java.lang.String, java.lang.String>]

Obviously a converter is needed, but how does one look like and how to wire it to the Map?显然需要一个转换器,但它的外观如何以及如何将其连接到 Map?

There are a couple of issue here -这里有几个问题 -

  • First spring properties does not allow camel casing in the properties file, It will throw an exception when reading the properties file including camel casing.首先 spring 属性不允许在属性文件中使用驼峰式大小写,读取包含驼峰式大小写的属性文件时会抛出异常。
  • There is no way you can capture property key inside a custom converter, spring will try to find the maching keyName inside your property class TestDataProperties , for the first key key1 it will try to find a field with key1 name.您无法在自定义转换器中捕获属性键, spring 将尝试在您的属性 class TestDataProperties中找到匹配的 keyName ,对于第一个键key1 ,它将尝试查找具有 key1 名称的字段。

Right now the program load the testData.properties and while parsing the properties file it is trying to look for the name key1 but there no key1, instead there is testData property thus testData is always nut in your code.现在程序加载 testData.properties 并在解析属性文件时尝试查找名称 key1 但没有 key1,而是有 testData 属性,因此 testData 在您的代码中始终是坚果。

Since spring does not allow for camel casing properties you can update testData.properties like so (the convention is to use hyphen every time you want to used more that two words for a property name)-由于 spring 不允许骆驼外壳属性,因此您可以像这样更新testData.properties (约定是每次您想使用两个以上的词作为属性名称时都使用连字符)-

test.data.test-data.key1=myKey1,myValue1

Then You can change you code in the following way -然后您可以通过以下方式更改您的代码 -

TestDataProperties.java TestDataProperties.java

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import java.util.AbstractMap;

@Component
@PropertySource(value = "classpath:testData.properties")
@ConfigurationProperties(prefix = "test.data.test-data")
public class TestDataProperties {

    private AbstractMap.SimpleEntry<String, String> key1;

    TestDataProperties(){

    }

    public AbstractMap.SimpleEntry<String, String> getKey1() {
        return key1;
    }

    public void setKey1(AbstractMap.SimpleEntry<String, String> key1) {
        this.key1 = key1;
    }
}

Secondly create custom converter to handle the data conversion while parsing the properties file -其次,在解析属性文件时创建自定义转换器来处理数据转换 -

CustomConverter.java CustomConverter.java

import org.springframework.boot.context.properties.ConfigurationPropertiesBinding;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

import java.util.AbstractMap;

@Component
@ConfigurationPropertiesBinding
public class CustomConverter implements Converter<String, AbstractMap.SimpleEntry<String, String>> {


    @Override
    public AbstractMap.SimpleEntry<String, String> convert(String data) {
        if(data != null && !data.isEmpty()){
            String[] values = data.trim().split(",");
            if(values.length == 2){
                return new AbstractMap.SimpleEntry<>(values[0], values[1]);
            }
        }
        return null;
    }
}

Finally you can autowire your TestDataProperties class as最后,您可以将您的TestDataProperties class 自动连接为

@Autowired
private TestDataProperties testDataProperties; 

Then you can access the properties like this -然后你可以访问这样的属性 -

testDataProperties.getKey1().getKey();
testDataProperties.getKey1().getValue();

Hope this helps!希望这可以帮助!

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

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