String replacement in java, similar to a velocity template

Viewed 159879

Is there any String replacement mechanism in Java, where I can pass objects with a text, and it replaces the string as it occurs.
For example, the text is :

Hello ${user.name},
    Welcome to ${site.name}. 

The objects I have are "user" and "site". I want to replace the strings given inside ${} with its equivalent values from the objects. This is same as we replace objects in a velocity template.

11 Answers

My preferred way is String.format() because its a oneliner and doesn't require third party libraries:

String message = String.format("Hello! My name is %s, I'm %s.", name, age); 

I use this regularly, e.g. in exception messages like:

throw new Exception(String.format("Unable to login with email: %s", email));

Hint: You can put in as many variables as you like because format() uses Varargs

Handlebars.java might be a better option in terms of a Velocity-like syntax with other server-side templating features.

http://jknack.github.io/handlebars.java/

Handlebars handlebars = new Handlebars();
Template template = handlebars.compileInline("Hello {{this}}!");
System.out.println(template.apply("Handlebars.java"));

I use GroovyShell in java to parse template with Groovy GString:

Binding binding = new Binding();
GroovyShell gs = new GroovyShell(binding);
// this JSONObject can also be replaced by any Java Object
JSONObject obj = new JSONObject();
obj.put("key", "value");
binding.setProperty("obj", obj)
String str = "${obj.key}";
String exp = String.format("\"%s\".toString()", str);
String res = (String) gs.evaluate(exp);
// value
System.out.println(str);

I created this utility that uses vanilla Java. It combines two formats... {} and %s style from String.format.... into one method call. Please note it only replaces empty {} brackets, not {someWord}.

public class LogUtils {

    public static String populate(String log, Object... objects) {
        log = log.replaceAll("\\{\\}", "%s");
        return String.format(log, objects);
    }

    public static void main(String[] args) {
        System.out.println(populate("x = %s, y ={}", 5, 4));;
    }

}

Since Java 15 you have the method String.formatted() (see documentation).

str.formatted(args) is the equivalent of String.format(str, args) with less ceremony.

For the example mentioned in the question, the method could be used as follow:

"Hello %s, Welcome to %s.".formatted(user.getName(), site.getName())
Related