07 — Advanced
Message Resolution
Rule violations carry messages that describe what went wrong. With rulii-spring, those messages can be externalized to application.properties or application.yml, making them easy to manage and change without touching code.
SpringEnvironmentMessageResolver
This is the default MessageResolver auto-configured by rulii-spring. It reads message codes from Spring's Environment, which means any property source works — properties files, YAML, environment variables, or Spring Cloud Config.
public class SpringEnvironmentMessageResolver implements MessageResolver {
public String resolve(Locale locale, String code, String defaultMessage) {
return environment.getProperty(code, defaultMessage);
}
}
The locale parameter is accepted but not used for resolution — Spring's Environment resolves properties by key only. If you need locale-aware resolution, you can override the MessageResolver bean with one backed by Spring's MessageSource.
Externalizing Messages
Define message codes in your properties file:
# application.properties
rule.age.tooYoung=Must be at least {0} years old
rule.credit.insufficient=Insufficient credit for amount {0}
rule.email.invalid=Please provide a valid email address
Or in YAML:
# application.yml
rule:
age:
tooYoung: "Must be at least {0} years old"
credit:
insufficient: "Insufficient credit for amount {0}"
Using Messages in Rules
When you reference a message code in a rule violation, the resolver looks it up from the environment. If the code isn't found, the default message is used instead.
// The message code "rule.age.tooYoung" is resolved from properties
// If not found, the default message is used
messageResolver.resolve(
Locale.getDefault(),
"rule.age.tooYoung",
"Age requirement not met"
);
// Returns: "Must be at least {0} years old"
Profile-Specific Messages
Since resolution uses Spring's Environment, you can leverage Spring profiles to provide different messages per environment. Messages in application-prod.properties override those in application.properties when the prod profile is active.
Custom MessageResolver
To replace the default resolver (for example, to use Spring's MessageSource for i18n), declare your own bean:
@Bean
public MessageResolver messageResolver(MessageSource messageSource) {
return (locale, code, defaultMessage) ->
messageSource.getMessage(code, null, defaultMessage, locale);
}
This overrides the auto-configured SpringEnvironmentMessageResolver and enables full locale-aware message resolution.