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:
| Library | Description | Use Case |
|---|---|---|
| Thymeleaf | Natural templating engine for Spring | HTML views, emails |
| FreeMarker | Lightweight and powerful | Dynamic web templates |
| Velocity | Apache project for server-side templating | Email generation, document rendering |
| Mustache.java | Logic-less templates | Simple 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 Case | Recommended Solution |
|---|---|
| Simple text replacement | String.replace() or StringSubstitutor |
| Localized messages | MessageFormat or Spring MessageSource |
| Application configuration | Spring placeholders (@Value) |
| HTML templates or emails | Thymeleaf, 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.


