Skip to content

Commit 4d97a05

Browse files
committed
SpringValidatorAdapter applies MessageFormat to {0}-containing message
Closes gh-23014
1 parent 1e76e50 commit 4d97a05

File tree

1 file changed

+26
-2
lines changed

1 file changed

+26
-2
lines changed

spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ protected void processConstraintViolations(Set<ConstraintViolation<Object>> viol
169169
errors.getObjectName(), errorCodes, errorArgs, violation.getMessage()) {
170170
@Override
171171
public boolean shouldRenderDefaultMessage() {
172-
return false;
172+
return requiresMessageFormat(violation);
173173
}
174174
};
175175
error.wrap(violation);
@@ -182,7 +182,7 @@ public boolean shouldRenderDefaultMessage() {
182182
rejectedValue, false, errorCodes, errorArgs, violation.getMessage()) {
183183
@Override
184184
public boolean shouldRenderDefaultMessage() {
185-
return false;
185+
return requiresMessageFormat(violation);
186186
}
187187
};
188188
error.wrap(violation);
@@ -300,12 +300,36 @@ protected Object[] getArgumentsForConstraint(String objectName, String field, Co
300300
* @param field the field that caused the binding error
301301
* @return a corresponding {@code MessageSourceResolvable} for the specified field
302302
* @since 4.3
303+
* @see #getArgumentsForConstraint
303304
*/
304305
protected MessageSourceResolvable getResolvableField(String objectName, String field) {
305306
String[] codes = new String[] {objectName + Errors.NESTED_PATH_SEPARATOR + field, field};
306307
return new DefaultMessageSourceResolvable(codes, field);
307308
}
308309

310+
/**
311+
* Indicate whether this violation's interpolated message has remaining
312+
* placeholders and therefore requires {@link java.text.MessageFormat}
313+
* to be applied to it. Called for a Bean Validation defined message
314+
* (coming out {@code ValidationMessages.properties}) when rendered
315+
* as the default message in Spring's MessageSource.
316+
* <p>The default implementation considers a Spring-style "{0}" placeholder
317+
* for the field name as an indication for {@link java.text.MessageFormat}.
318+
* Any other placeholder or escape syntax occurrences are typically a
319+
* mismatch, coming out of regex pattern values or the like. Note that
320+
* standard Bean Validation does not support "{0}" style placeholders at all;
321+
* this is a feature typically used in Spring MessageSource resource bundles.
322+
* @param violation the Bean Validation constraint violation, including
323+
* BV-defined interpolation of named attribute references in its message
324+
* @return {@code true} if {@code java.text.MessageFormat} is to be applied,
325+
* or {@code false} if the violation's message should be used as-is
326+
* @since 5.1.8
327+
* @see #getArgumentsForConstraint
328+
*/
329+
protected boolean requiresMessageFormat(ConstraintViolation<?> violation) {
330+
return violation.getMessage().contains("{0}");
331+
}
332+
309333
/**
310334
* Extract the rejected value behind the given constraint violation,
311335
* for exposure through the Spring errors representation.

0 commit comments

Comments
 (0)