diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/validation/MessageSourceMessageInterpolator.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/validation/MessageSourceMessageInterpolator.java index 07363390b1e..8287262b10e 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/validation/MessageSourceMessageInterpolator.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/validation/MessageSourceMessageInterpolator.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,6 +34,8 @@ import org.springframework.context.i18n.LocaleContextHolder; */ class MessageSourceMessageInterpolator implements MessageInterpolator { + private static final String DEFAULT_MESSAGE = MessageSourceMessageInterpolator.class.getName(); + private static final char PREFIX = '{'; private static final char SUFFIX = '}'; @@ -115,13 +117,11 @@ class MessageSourceMessageInterpolator implements MessageInterpolator { private String replaceParameter(String parameter, Locale locale, Set visitedParameters) { parameter = replaceParameters(parameter, locale, visitedParameters); - String value = this.messageSource.getMessage(parameter, null, null, locale); - return (value != null && !isUsingCodeAsDefaultMessage(value, parameter)) - ? replaceParameters(value, locale, visitedParameters) : null; - } - - private boolean isUsingCodeAsDefaultMessage(String value, String parameter) { - return value.equals(parameter); + String value = this.messageSource.getMessage(parameter, null, DEFAULT_MESSAGE, locale); + if (value == null || value.equals(DEFAULT_MESSAGE)) { + return null; + } + return replaceParameters(value, locale, visitedParameters); } } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/validation/MessageSourceMessageInterpolatorTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/validation/MessageSourceMessageInterpolatorTests.java index 66653ef9ad7..63e427511c8 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/validation/MessageSourceMessageInterpolatorTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/validation/MessageSourceMessageInterpolatorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -66,6 +66,19 @@ class MessageSourceMessageInterpolatorTests { .isEqualTo("{foo}{child}+{child}{bar}"); } + @Test + void interpolateShouldReplaceParameterThatReferencesAMessageThatMatchesItsCode() { + this.messageSource.addMessage("foo", Locale.getDefault(), "foo"); + assertThat(this.interpolator.interpolate("{foo}", this.context)).isEqualTo("foo"); + } + + @Test + void interpolateUsingCodeAsDefaultShouldReplaceParameterThatReferencesAMessageThatMatchesItsCode() { + this.messageSource.setUseCodeAsDefaultMessage(true); + this.messageSource.addMessage("foo", Locale.getDefault(), "foo"); + assertThat(this.interpolator.interpolate("{foo}", this.context)).isEqualTo("foo"); + } + @Test void interpolateWhenParametersAreNestedShouldFullyReplaceAllParameters() { this.messageSource.addMessage("top", Locale.getDefault(), "{child}+{child}");