Substitute a String in Java by replace variables map to Template String using Apache Commons Text

Tags: Apache Commons Apache Commons Text StringSubstitutor String

Introduction

In this post we are going to learn how to substitute a String in Java which replaces variables into placeholders in a template String. To do this task we will use the Apache Commons Text library with support of StringSubstitutor class. Via different Java example code we will learn how to apply StringSubstitutor in different scenarios in your Java applications.

Setup Apache Commons Text in Java project

If you are using Gradle build then add the following dependency configuration into build.gradle file.

compile group: 'org.apache.commons', name: 'commons-text', version: '1.9'

Or add the following dependency XML tag to pom.xml file if you are using Maven build.

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-text</artifactId>
    <version>1.9</version>
</dependency>

Or download commons-text-1.9.jar file from Apache Commons Text download page at commons.apache.org

How to use org.apache.commons.text.StringSubstitutor

In other to substitute a String you need to prepare

  • The template String which contains placeholders in syntax as ${variableName}

  • A map of variables whose key is placeholder name in your template String and value is the value you want to replace.

Java code example with given template String and map of variable

import org.apache.commons.text.StringSubstitutor;

import java.util.HashMap;
import java.util.Map;

public class StringSubstitutorExample1 {
    public static void main(String[] args) {
        // Template String
        String templateString = "Hello ${name},\nPlease find attached invoice ${invoiceNumber} which is due on ${dueDate}.";

        // Prepare value map of variables to replace to template String
        Map<String, String> valuesMap = new HashMap<>();
        valuesMap.put("name", "John");
        valuesMap.put("invoiceNumber", "ABC123");
        valuesMap.put("dueDate", "20 October 2020");

        // Initialize StringSubstitutor instance with value map
        StringSubstitutor stringSubstitutor = new StringSubstitutor(valuesMap);

        // replace value map to template string
        String result = stringSubstitutor.replace(templateString);

        System.out.println(result);
    }
}
Output:

Hello John,
Please find attached invoice ABC123 which is due on 20 October 2020.

Java code example with default value in template String

The StringSubstitutor class support define default value for your variable in syntax ${variableName:-defaultValue} with default value define after :-

import org.apache.commons.text.StringSubstitutor;

import java.util.HashMap;
import java.util.Map;

public class StringSubstitutorExample2 {
    public static void main(String[] args) {
        // Template String
        String templateString = "Hello ${username}, you have ${count:-0} messages.";

        // Prepare value map of variables to replace to template String
        // This value map does not provide "count" key value pair
        Map<String, String> valuesMap = new HashMap<>();
        valuesMap.put("username", "Ben");

        // Initialize StringSubstitutor instance with value map
        StringSubstitutor stringSubstitutor = new StringSubstitutor(valuesMap);

        // replace value map to template string
        String result = stringSubstitutor.replace(templateString);

        System.out.println(result);
    }
}
Output:

Hello Ben, you have 0 messages.

Java code example that does not provide enough variable

In case the variable map does not provide a variable then the output String will keep your variable name as defined in template.

import org.apache.commons.text.StringSubstitutor;

import java.util.HashMap;
import java.util.Map;

public class StringSubstitutorExample3 {
    public static void main(String[] args) {
        // Template String
        String templateString = "The account ${accountNumber} balance is ${balance} dollars.";

        // Prepare value map of variables to replace to template String
        // This value map does not provide "balance" key value pair
        Map<String, String> valuesMap = new HashMap<>();
        valuesMap.put("accountNumber", "SS12345");

        // Initialize StringSubstitutor instance with value map
        StringSubstitutor stringSubstitutor = new StringSubstitutor(valuesMap);

        // replace value map to template string
        String result = stringSubstitutor.replace(templateString);

        System.out.println(result);
    }
}
Output:

The account SS12345 balance is ${balance} dollars.

Java code example that setting to throw exception if any variable undefined

The StringSubstitutor class also allows you to set a flag to allow it to throw an exception if any variable is undefined by using setEnableUndefinedVariableException() method.

import org.apache.commons.text.StringSubstitutor;

import java.util.HashMap;
import java.util.Map;

public class StringSubstitutorExample4 {
    public static void main(String[] args) {
        try {
            String templateString = "The account ${accountNumber} balance is ${balance} dollars.";

            // the value map does not define "balance" variable
            Map<String, String> valuesMap = new HashMap<>();
            valuesMap.put("accountNumber", "SS12345");

            StringSubstitutor stringSubstitutor = new StringSubstitutor(valuesMap);

            // Sets this flag to true to throw exception if any variable is undefined.
            stringSubstitutor.setEnableUndefinedVariableException(true);
            String result = stringSubstitutor.replace(templateString);

            System.out.println(result);
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }
}
Output:

java.lang.IllegalArgumentException: Cannot resolve variable 'balance' (enableSubstitutionInVariables=false).
	at org.apache.commons.text.StringSubstitutor.substitute(StringSubstitutor.java:1451)
	at org.apache.commons.text.StringSubstitutor.substitute(StringSubstitutor.java:1308)
	at org.apache.commons.text.StringSubstitutor.replace(StringSubstitutor.java:816)
	at StringSubstitutorExample4.main(StringSubstitutorExample4.java:19)

Java code example how to use StringSubstitutor.replaceSystemProperties()

Instead of a given map of variables you can replace with system properties as example code below.

import org.apache.commons.text.StringSubstitutor;

public class StringSubstitutorExample5 {
    public static void main(String[] args) {
        String templateString = "Java version: ${java.version} \nOperating system: ${os.name}";

        String result = StringSubstitutor.replaceSystemProperties(templateString);

        System.out.println(result);
    }
}
Output:

Java version: 1.8.0_231 
Operating system: Windows 10

Happy Coding 😊