Michael Osipov opened SPR-13590 and commented
Consider this code snippet:
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
public ResponseEntity<RestError> handleMethodArgumentTypeMismatchException(
MethodArgumentTypeMismatchException e) {
String message = messages.getMessage(
"error.projects.invalid_parameter." + e.getName() + ".type_mismatch",
new Object[] { e.getValue(), e.getName() },
messages.getMessage("error.projects.invalid_parameter.type_mismatch", new Object[] {
e.getValue(), e.getName() }));
RestError error = new RestError(Reason.INVALID_PARAMETER, message;
return new ResponseEntity<RestError>(error, HttpStatus.BAD_REQUEST);
}
using the following signature:
public String getMessage(String code, Object[] args, String defaultMessage)
Where bundle looks like
error.projects.invalid_parameter.type_mismatch = Der \u00FCbergebene Wert ''{0}'' für Parameter ''{1}'' ist fehlerhaft/ung\u00FCltig
The default message shall provide a generic information if a parameter-specific message code is not available.
The expected behavior is:
Der übergebene Wert 'dd' für Parameter 'omitEmptyResponse' ist fehlerhaft/ungültig
but the output is:
Der übergebene Wert dd für Parameter omitEmptyResponse ist fehlerhaft/ungültig
The quotes are lost because the default message is passed through MessageFormat
. This behavior is not documented. The signature says: code
and defaultMessage
and not code
and defaultCode
.
This is either bad documentation or bad implementation. I opt for the latter.
The outcome is that one needs to double-escape the quotes. Making them unusable for code
but only for defaultMessage
.
Affects: 4.2.2
Comment From: jhoeller
The above is actually a bit of a misunderstanding since the defaultMessage
argument is not supposed to be a pre-resolved message but rather a message template which still gets the provided arguments substituted. From that perspective, this works as designed.