简体   繁体   中英

Java concatenation in properties file

I have created a properties file called myproperties.properties as:

test.value1=one
test.value2=two

My java code to read this file is the following:

String test = Utility.getInstance().getProperty("test.value1");

where class Utility is so defined:

public class Utility {

    private static Utility _instance = null;
    private static Properties properties = new Properties();

    static public Utility getInstance(){
        if (_instance == null) {
            _instance = new Utility();
        }
        return _instance;
    }

    private Utility(){
        loadUtility();
    }

    public String getProperty(String tgtPropertyName) {
        Object prop = properties.get(tgtPropertyName);

        if (prop != null) {
            return prop.toString();
        } else {
            return null;
        }
    }

    private void loadUtility(){
        String filename = null;
        try{
            filename = getClass().getClassLoader().getResource("myproperties").getFile();
            InputStream file = new FileInputStream(new File(filename));
            properties.load(file);
            Iterator iter = properties.keySet().iterator();
            while (iter.hasNext()){
                System.out.println("FILE LOADED");
            }
        }catch(Exception e){
        }    
    }

}

This code works correctly. Now I must add a concatenation in my properties file:

test.value3=${test.value1}${test.value2}

and this not worked because my Java code cannot interpret ${}.

The exception is:

Caused by: java.lang.IllegalStateException: Stream handler unavailable due to: For input string: "${test.value1}"

Why?

Use below code to concatenate in type.value3 in properties file

Properties prop=null;
public FileReader FileLoader() throws FileNotFoundException
{
    File file=new File("myproperties.properties");
    FileReader fileReader=new FileReader(file);
    return fileReader;

}
public String propertyLoader(String key) throws IOException
{
    FileReader fileReader=FileLoader();
    prop=new Properties();
    prop.load(fileReader);
    String value=prop.getProperty(key);

    return value;

}
public void resultWriter() throws IOException
{
    String value1=propertyLoader("test.value1");
    String value2=propertyLoader("test.value2");
    String res=value1+value2;
    System.out.println(res);
    FileWriter fw=new FileWriter("myproperties.properties");
    prop=new Properties();
    prop.setProperty("test.value3", res);
    prop.store(fw, null);


}
public static void main(String[] args) throws IOException 
{
    UtilityNew util=new UtilityNew();
    util.resultWriter();
    System.out.println("Success");

}

Nested properties are not supported in core Java. The only thing you can do is create a class that is going to resolve the ${XXX} values once you have loaded the file.properties into a Properties object.

Or maybe the typesafe library can be usefull to you. https://github.com/lightbend/config . It has a lot of functionalities and one of them is substitutions:

substitutions ("foo" : ${bar}, "foo" : Hello ${who})

But you won't have a key-value properties file anymore, it will look more like a json file.

This might be a late answer but someone might find this useful.

You can write a small utility function which reads the property values and then iteratively replaces any nested values that are present First search for your pattern. Replace it with the actual value by looking-up at the properties. Repeat this until you get the final string.

Properties properties = new Properties();
properties.setProperty("base_url", "http://base");
properties.setProperty("subs_url", "${base_url}/subs");
properties.setProperty("app_download", "apps/download");
properties.setProperty("subs_detail", "${subs_url}/detail/${app_download}");


String input = properties.getProperty("subs_detail");
Pattern pattern = Pattern.compile("\\$\\{.*?\\}"); //change the pattern here to find nested values

while (pattern.matcher(input).find())
{
  Matcher match = pattern.matcher(input);
  while (match.find())
  {
    input = input.replace(match.group(), properties.getProperty(match.group().substring(2, match.group().length()-1)));
  }
}

System.out.println("final String : " + input); // this prints http://base/subs/detail/apps/download

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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