Templating and Placeholder Replacement in Java and Spring

In modern Java applications, generating dynamic text is a common need — whether it’s building personalized email content, log messages, SQL queries, or configuration templates. Templating and placeholder replacement allow developers to inject values dynamically into predefined strings or files.

This article explores different ways to handle templating and placeholder replacement in Java — from simple string operations to more advanced Spring-specific solutions.


1. Basic Placeholder Replacement Using String.replace()

For simple use cases, such as replacing a static placeholder in a text, the easiest way is to use the replace() method of the String class.

String template = "Hello, {name}! Welcome to our platform.";
String result = template.replace("{name}", "Alice");
System.out.println(result);
// Output: Hello, Alice! Welcome to our platform.

Pros:

  • Very simple and fast.
  • Works well when placeholders are known and unique.

Cons:

  • Not flexible for multiple variables or dynamic placeholders.
  • No error handling for missing values.

2. Using Regular Expressions with replaceAll()

If your placeholders follow a pattern, like {{variable}}, you can use regular expressions with replaceAll():

String template = "Your order {{orderId}} has been shipped to {{address}}.";
String result = template
    .replaceAll("\\{\\{orderId\\}\\}", "A12345")
    .replaceAll("\\{\\{address\\}\\}", "Bucharest, Romania");

System.out.println(result);
// Output: Your order A12345 has been shipped to Bucharest, Romania.

Tip: Always escape braces and special regex characters properly (\\{\\{name\\}\\}).


3. Using MessageFormat for Structured Templates

The java.text.MessageFormat class is designed for formatting messages with indexed placeholders, useful in internationalization and formatted outputs.

import java.text.MessageFormat;

String pattern = "Dear {0}, your account balance is {1,number,currency}.";
String result = MessageFormat.format(pattern, "Alice", 1520.75);
System.out.println(result);
// Output: Dear Alice, your account balance is $1,520.75.

Advantages:

  • Supports numbers, dates, and locale-aware formatting.
  • Integrates well with internationalized applications.

Limitation:
Placeholders are index-based ({0}, {1}), not named, which can reduce readability.


4. Using Apache Commons Text StringSubstitutor

For named variables, Apache Commons Text provides a powerful and flexible solution: StringSubstitutor.

import org.apache.commons.text.StringSubstitutor;
import java.util.Map;

Map<String, String> values = Map.of(
    "user", "Alice",
    "product", "BookViewer",
    "price", "29.99"
);

String template = "Hello ${user}, your ${product} is now available for $${price}.";
StringSubstitutor sub = new StringSubstitutor(values);
String result = sub.replace(template);

System.out.println(result);
// Output: Hello Alice, your BookViewer is now available for $29.99.

Why use it:

  • Supports nested variables and defaults.
  • Easy to configure with custom prefixes/suffixes.
  • Can read from maps, properties files, or system environment variables.

5. Spring Boot Property Placeholder Resolution

In Spring, placeholder resolution is built into the framework and commonly used for configuration.

Example: You can define placeholders in application.properties and use them in beans or annotations.

app.name=MyApplication
app.welcome=Welcome to ${app.name}!

You can inject these values using @Value:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class WelcomeService {

    @Value("${app.welcome}")
    private String welcomeMessage;

    public void greetUser() {
        System.out.println(welcomeMessage);
    }
}

Spring automatically resolves ${app.name} inside ${app.welcome}.

Note: Spring also supports nested placeholders and environment variable overrides (e.g., ${HOME}).


6. Using Spring’s PropertySourcesPlaceholderConfigurer

For non-Spring Boot projects or advanced configuration setups, you can manually register a PropertySourcesPlaceholderConfigurer bean.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;

@Configuration
public class AppConfig {
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyConfig() {
        return new PropertySourcesPlaceholderConfigurer();
    }
}

Then you can use the same ${...} placeholders in XML or annotation-based configuration.


7. Using Spring’s MessageSource for Localization Templates

If you want placeholders that depend on the user’s locale, use MessageSource with resource bundles.

messages.properties

welcome.message=Hello, {0}! You have {1} new notifications.

Java Code

import org.springframework.context.MessageSource;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Locale;

MessageSource messageSource = new ClassPathXmlApplicationContext("beans.xml");
String message = messageSource.getMessage("welcome.message",
        new Object[]{"Alice", 5}, Locale.ENGLISH);
System.out.println(message);
// Output: Hello, Alice! You have 5 new notifications.

This approach is perfect for internationalized messages with dynamic values.


8. Advanced Templating Libraries in Java

For more complex templates (e.g., HTML emails, reports, or configuration files), Java developers often rely on dedicated templating engines:

LibraryDescriptionUse Case
ThymeleafNatural templating engine for SpringHTML views, emails
FreeMarkerLightweight and powerfulDynamic web templates
VelocityApache project for server-side templatingEmail generation, document rendering
Mustache.javaLogic-less templatesSimple and lightweight views

Example with Thymeleaf (Spring Boot integration):

@Autowired
private TemplateEngine templateEngine;

public String buildEmail(String name) {
    Context context = new Context();
    context.setVariable("name", name);
    return templateEngine.process("welcome-email", context);
}

9. Choosing the Right Approach

Use CaseRecommended Solution
Simple text replacementString.replace() or StringSubstitutor
Localized messagesMessageFormat or Spring MessageSource
Application configurationSpring placeholders (@Value)
HTML templates or emailsThymeleaf, FreeMarker, or Velocity

Conclusion

Templating and placeholder replacement are essential techniques for building flexible, dynamic, and localized Java applications.

From simple string manipulation to powerful Spring templating, the right approach depends on your use case — simplicity for fixed templates, or structured frameworks like Thymeleaf for full-featured dynamic rendering.

By understanding these techniques, developers can write cleaner, more maintainable, and reusable code for any Java or Spring project.

This article is inspired by real-world challenges we tackle in our projects. If you're looking for expert solutions or need a team to bring your idea to life,

Let's talk!

    Please fill your details, and we will contact you back

      Please fill your details, and we will contact you back