Polishing in Web validation exceptions
- Update method order - Do not automatically create MessageSource arguments in WebExchangeBindException constructor as they're more likely to be created via getDetailMessageArguments with MessageSource passed in. See gh-30644
This commit is contained in:
parent
a8ea472121
commit
e83594a2a3
|
|
@ -64,6 +64,13 @@ public class MethodArgumentNotValidException extends BindException implements Er
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the method parameter that failed validation.
|
||||||
|
*/
|
||||||
|
public final MethodParameter getParameter() {
|
||||||
|
return this.parameter;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpStatusCode getStatusCode() {
|
public HttpStatusCode getStatusCode() {
|
||||||
return HttpStatus.BAD_REQUEST;
|
return HttpStatus.BAD_REQUEST;
|
||||||
|
|
@ -74,67 +81,31 @@ public class MethodArgumentNotValidException extends BindException implements Er
|
||||||
return this.body;
|
return this.body;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the method parameter that failed validation.
|
|
||||||
*/
|
|
||||||
public final MethodParameter getParameter() {
|
|
||||||
return this.parameter;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMessage() {
|
|
||||||
StringBuilder sb = new StringBuilder("Validation failed for argument [")
|
|
||||||
.append(this.parameter.getParameterIndex()).append("] in ")
|
|
||||||
.append(this.parameter.getExecutable().toGenericString());
|
|
||||||
BindingResult bindingResult = getBindingResult();
|
|
||||||
if (bindingResult.getErrorCount() > 1) {
|
|
||||||
sb.append(" with ").append(bindingResult.getErrorCount()).append(" errors");
|
|
||||||
}
|
|
||||||
sb.append(": ");
|
|
||||||
for (ObjectError error : bindingResult.getAllErrors()) {
|
|
||||||
sb.append('[').append(error).append("] ");
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object[] getDetailMessageArguments() {
|
public Object[] getDetailMessageArguments() {
|
||||||
return new Object[] {
|
return new Object[] {
|
||||||
join(formatErrors(getGlobalErrors(), null, null)),
|
join(errorsToStringList(getGlobalErrors())),
|
||||||
join(formatErrors(getFieldErrors(), null, null))};
|
join(errorsToStringList(getFieldErrors()))};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object[] getDetailMessageArguments(MessageSource messageSource, Locale locale) {
|
public Object[] getDetailMessageArguments(MessageSource messageSource, Locale locale) {
|
||||||
return new Object[] {
|
return new Object[] {
|
||||||
join(formatErrors(getGlobalErrors(), messageSource, locale)),
|
join(errorsToStringList(getGlobalErrors(), messageSource, locale)),
|
||||||
join(formatErrors(getFieldErrors(), messageSource, locale))};
|
join(errorsToStringList(getFieldErrors(), messageSource, locale))};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String join(List<String> errors) {
|
private static String join(List<String> errors) {
|
||||||
return String.join(", and ", errors);
|
return String.join(", and ", errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolve global and field errors to messages with the given
|
|
||||||
* {@link MessageSource} and {@link Locale}.
|
|
||||||
* @return a Map with errors as keys and resolved messages as values
|
|
||||||
* @since 6.0.3
|
|
||||||
*/
|
|
||||||
public Map<ObjectError, String> resolveErrorMessages(MessageSource source, Locale locale) {
|
|
||||||
Map<ObjectError, String> map = new LinkedHashMap<>(getErrorCount());
|
|
||||||
getGlobalErrors().forEach(error -> map.put(error, formatError(error, source, locale)));
|
|
||||||
getFieldErrors().forEach(error -> map.put(error, formatError(error, source, locale)));
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert each given {@link ObjectError} to a String in single quotes, taking
|
* Convert each given {@link ObjectError} to a String in single quotes, taking
|
||||||
* either the error's default message, or its error code.
|
* either the error's default message, or its error code.
|
||||||
* @since 6.0
|
* @since 6.0
|
||||||
*/
|
*/
|
||||||
public static List<String> errorsToStringList(List<? extends ObjectError> errors) {
|
public static List<String> errorsToStringList(List<? extends ObjectError> errors) {
|
||||||
return formatErrors(errors, null, null);
|
return errorsToStringList(errors, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -144,12 +115,6 @@ public class MethodArgumentNotValidException extends BindException implements Er
|
||||||
* @since 6.0
|
* @since 6.0
|
||||||
*/
|
*/
|
||||||
public static List<String> errorsToStringList(
|
public static List<String> errorsToStringList(
|
||||||
List<? extends ObjectError> errors, @Nullable MessageSource source, Locale locale) {
|
|
||||||
|
|
||||||
return formatErrors(errors, source, locale);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<String> formatErrors(
|
|
||||||
List<? extends ObjectError> errors, @Nullable MessageSource messageSource, @Nullable Locale locale) {
|
List<? extends ObjectError> errors, @Nullable MessageSource messageSource, @Nullable Locale locale) {
|
||||||
|
|
||||||
return errors.stream()
|
return errors.stream()
|
||||||
|
|
@ -170,4 +135,33 @@ public class MethodArgumentNotValidException extends BindException implements Er
|
||||||
return (field + message);
|
return (field + message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve global and field errors to messages with the given
|
||||||
|
* {@link MessageSource} and {@link Locale}.
|
||||||
|
* @return a Map with errors as keys and resolved messages as values
|
||||||
|
* @since 6.0.3
|
||||||
|
*/
|
||||||
|
public Map<ObjectError, String> resolveErrorMessages(MessageSource source, Locale locale) {
|
||||||
|
Map<ObjectError, String> map = new LinkedHashMap<>(getErrorCount());
|
||||||
|
getGlobalErrors().forEach(error -> map.put(error, formatError(error, source, locale)));
|
||||||
|
getFieldErrors().forEach(error -> map.put(error, formatError(error, source, locale)));
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMessage() {
|
||||||
|
StringBuilder sb = new StringBuilder("Validation failed for argument [")
|
||||||
|
.append(this.parameter.getParameterIndex()).append("] in ")
|
||||||
|
.append(this.parameter.getExecutable().toGenericString());
|
||||||
|
BindingResult bindingResult = getBindingResult();
|
||||||
|
if (bindingResult.getErrorCount() > 1) {
|
||||||
|
sb.append(" with ").append(bindingResult.getErrorCount()).append(" errors");
|
||||||
|
}
|
||||||
|
sb.append(": ");
|
||||||
|
for (ObjectError error : bindingResult.getAllErrors()) {
|
||||||
|
sb.append('[').append(error).append("] ");
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,20 +49,11 @@ public class WebExchangeBindException extends ServerWebInputException implements
|
||||||
|
|
||||||
|
|
||||||
public WebExchangeBindException(MethodParameter parameter, BindingResult bindingResult) {
|
public WebExchangeBindException(MethodParameter parameter, BindingResult bindingResult) {
|
||||||
super("Validation failure", parameter, null, null, initMessageDetailArguments(bindingResult));
|
super("Validation failure", parameter, null, null, null);
|
||||||
this.bindingResult = bindingResult;
|
this.bindingResult = bindingResult;
|
||||||
getBody().setDetail("Invalid request content.");
|
getBody().setDetail("Invalid request content.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Object[] initMessageDetailArguments(BindingResult bindingResult) {
|
|
||||||
return new Object[] {
|
|
||||||
join(MethodArgumentNotValidException.errorsToStringList(bindingResult.getGlobalErrors())),
|
|
||||||
join(MethodArgumentNotValidException.errorsToStringList(bindingResult.getFieldErrors()))};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String join(List<String> errors) {
|
|
||||||
return String.join(", and ", errors);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the BindingResult that this BindException wraps.
|
* Return the BindingResult that this BindException wraps.
|
||||||
|
|
@ -73,6 +64,52 @@ public class WebExchangeBindException extends ServerWebInputException implements
|
||||||
return this.bindingResult;
|
return this.bindingResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object[] getDetailMessageArguments() {
|
||||||
|
return new Object[] {
|
||||||
|
join(MethodArgumentNotValidException.errorsToStringList(getGlobalErrors())),
|
||||||
|
join(MethodArgumentNotValidException.errorsToStringList(getFieldErrors()))};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object[] getDetailMessageArguments(MessageSource source, Locale locale) {
|
||||||
|
return new Object[] {
|
||||||
|
join(MethodArgumentNotValidException.errorsToStringList(getGlobalErrors(), source, locale)),
|
||||||
|
join(MethodArgumentNotValidException.errorsToStringList(getFieldErrors(), source, locale))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String join(List<String> errors) {
|
||||||
|
return String.join(", and ", errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve global and field errors to messages with the given
|
||||||
|
* {@link MessageSource} and {@link Locale}.
|
||||||
|
* @return a Map with errors as key and resolves messages as value
|
||||||
|
* @since 6.0.3
|
||||||
|
*/
|
||||||
|
public Map<ObjectError, String> resolveErrorMessages(MessageSource messageSource, Locale locale) {
|
||||||
|
Map<ObjectError, String> map = new LinkedHashMap<>();
|
||||||
|
addMessages(map, getGlobalErrors(), messageSource, locale);
|
||||||
|
addMessages(map, getFieldErrors(), messageSource, locale);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addMessages(
|
||||||
|
Map<ObjectError, String> map, List<? extends ObjectError> errors,
|
||||||
|
MessageSource messageSource, Locale locale) {
|
||||||
|
|
||||||
|
List<String> messages = MethodArgumentNotValidException.errorsToStringList(errors, messageSource, locale);
|
||||||
|
for (int i = 0; i < errors.size(); i++) {
|
||||||
|
map.put(errors.get(i), messages.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// BindingResult implementation methods
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getObjectName() {
|
public String getObjectName() {
|
||||||
return this.bindingResult.getObjectName();
|
return this.bindingResult.getObjectName();
|
||||||
|
|
@ -285,6 +322,7 @@ public class WebExchangeBindException extends ServerWebInputException implements
|
||||||
return this.bindingResult.getSuppressedFields();
|
return this.bindingResult.getSuppressedFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns diagnostic information about the errors held in this object.
|
* Returns diagnostic information about the errors held in this object.
|
||||||
*/
|
*/
|
||||||
|
|
@ -302,38 +340,6 @@ public class WebExchangeBindException extends ServerWebInputException implements
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object[] getDetailMessageArguments(MessageSource source, Locale locale) {
|
|
||||||
return new Object[] {
|
|
||||||
join(MethodArgumentNotValidException.errorsToStringList(getGlobalErrors(), source, locale)),
|
|
||||||
join(MethodArgumentNotValidException.errorsToStringList(getFieldErrors(), source, locale))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolve global and field errors to messages with the given
|
|
||||||
* {@link MessageSource} and {@link Locale}.
|
|
||||||
* @return a Map with errors as key and resolves messages as value
|
|
||||||
* @since 6.0.3
|
|
||||||
*/
|
|
||||||
public Map<ObjectError, String> resolveErrorMessages(MessageSource messageSource, Locale locale) {
|
|
||||||
Map<ObjectError, String> map = new LinkedHashMap<>();
|
|
||||||
addMessages(map, getGlobalErrors(), messageSource, locale);
|
|
||||||
addMessages(map, getFieldErrors(), messageSource, locale);
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void addMessages(
|
|
||||||
Map<ObjectError, String> map, List<? extends ObjectError> errors,
|
|
||||||
MessageSource messageSource, Locale locale) {
|
|
||||||
|
|
||||||
List<String> messages = MethodArgumentNotValidException.errorsToStringList(errors, messageSource, locale);
|
|
||||||
for (int i = 0; i < errors.size(); i++) {
|
|
||||||
map.put(errors.get(i), messages.get(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(@Nullable Object other) {
|
public boolean equals(@Nullable Object other) {
|
||||||
return (this == other || this.bindingResult.equals(other));
|
return (this == other || this.bindingResult.equals(other));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue