Skip to content

Commit e83594a

Browse files
committed
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
1 parent a8ea472 commit e83594a

File tree

2 files changed

+88
-88
lines changed

2 files changed

+88
-88
lines changed

spring-web/src/main/java/org/springframework/web/bind/MethodArgumentNotValidException.java

Lines changed: 41 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -64,16 +64,6 @@ public MethodArgumentNotValidException(MethodParameter parameter, BindingResult
6464
}
6565

6666

67-
@Override
68-
public HttpStatusCode getStatusCode() {
69-
return HttpStatus.BAD_REQUEST;
70-
}
71-
72-
@Override
73-
public ProblemDetail getBody() {
74-
return this.body;
75-
}
76-
7767
/**
7868
* Return the method parameter that failed validation.
7969
*/
@@ -82,59 +72,40 @@ public final MethodParameter getParameter() {
8272
}
8373

8474
@Override
85-
public String getMessage() {
86-
StringBuilder sb = new StringBuilder("Validation failed for argument [")
87-
.append(this.parameter.getParameterIndex()).append("] in ")
88-
.append(this.parameter.getExecutable().toGenericString());
89-
BindingResult bindingResult = getBindingResult();
90-
if (bindingResult.getErrorCount() > 1) {
91-
sb.append(" with ").append(bindingResult.getErrorCount()).append(" errors");
92-
}
93-
sb.append(": ");
94-
for (ObjectError error : bindingResult.getAllErrors()) {
95-
sb.append('[').append(error).append("] ");
96-
}
97-
return sb.toString();
75+
public HttpStatusCode getStatusCode() {
76+
return HttpStatus.BAD_REQUEST;
77+
}
78+
79+
@Override
80+
public ProblemDetail getBody() {
81+
return this.body;
9882
}
9983

10084
@Override
10185
public Object[] getDetailMessageArguments() {
10286
return new Object[] {
103-
join(formatErrors(getGlobalErrors(), null, null)),
104-
join(formatErrors(getFieldErrors(), null, null))};
87+
join(errorsToStringList(getGlobalErrors())),
88+
join(errorsToStringList(getFieldErrors()))};
10589
}
10690

10791
@Override
10892
public Object[] getDetailMessageArguments(MessageSource messageSource, Locale locale) {
10993
return new Object[] {
110-
join(formatErrors(getGlobalErrors(), messageSource, locale)),
111-
join(formatErrors(getFieldErrors(), messageSource, locale))};
94+
join(errorsToStringList(getGlobalErrors(), messageSource, locale)),
95+
join(errorsToStringList(getFieldErrors(), messageSource, locale))};
11296
}
11397

11498
private static String join(List<String> errors) {
11599
return String.join(", and ", errors);
116100
}
117101

118-
/**
119-
* Resolve global and field errors to messages with the given
120-
* {@link MessageSource} and {@link Locale}.
121-
* @return a Map with errors as keys and resolved messages as values
122-
* @since 6.0.3
123-
*/
124-
public Map<ObjectError, String> resolveErrorMessages(MessageSource source, Locale locale) {
125-
Map<ObjectError, String> map = new LinkedHashMap<>(getErrorCount());
126-
getGlobalErrors().forEach(error -> map.put(error, formatError(error, source, locale)));
127-
getFieldErrors().forEach(error -> map.put(error, formatError(error, source, locale)));
128-
return map;
129-
}
130-
131102
/**
132103
* Convert each given {@link ObjectError} to a String in single quotes, taking
133104
* either the error's default message, or its error code.
134105
* @since 6.0
135106
*/
136107
public static List<String> errorsToStringList(List<? extends ObjectError> errors) {
137-
return formatErrors(errors, null, null);
108+
return errorsToStringList(errors, null, null);
138109
}
139110

140111
/**
@@ -144,12 +115,6 @@ public static List<String> errorsToStringList(List<? extends ObjectError> errors
144115
* @since 6.0
145116
*/
146117
public static List<String> errorsToStringList(
147-
List<? extends ObjectError> errors, @Nullable MessageSource source, Locale locale) {
148-
149-
return formatErrors(errors, source, locale);
150-
}
151-
152-
public static List<String> formatErrors(
153118
List<? extends ObjectError> errors, @Nullable MessageSource messageSource, @Nullable Locale locale) {
154119

155120
return errors.stream()
@@ -170,4 +135,33 @@ private static String formatError(
170135
return (field + message);
171136
}
172137

138+
/**
139+
* Resolve global and field errors to messages with the given
140+
* {@link MessageSource} and {@link Locale}.
141+
* @return a Map with errors as keys and resolved messages as values
142+
* @since 6.0.3
143+
*/
144+
public Map<ObjectError, String> resolveErrorMessages(MessageSource source, Locale locale) {
145+
Map<ObjectError, String> map = new LinkedHashMap<>(getErrorCount());
146+
getGlobalErrors().forEach(error -> map.put(error, formatError(error, source, locale)));
147+
getFieldErrors().forEach(error -> map.put(error, formatError(error, source, locale)));
148+
return map;
149+
}
150+
151+
@Override
152+
public String getMessage() {
153+
StringBuilder sb = new StringBuilder("Validation failed for argument [")
154+
.append(this.parameter.getParameterIndex()).append("] in ")
155+
.append(this.parameter.getExecutable().toGenericString());
156+
BindingResult bindingResult = getBindingResult();
157+
if (bindingResult.getErrorCount() > 1) {
158+
sb.append(" with ").append(bindingResult.getErrorCount()).append(" errors");
159+
}
160+
sb.append(": ");
161+
for (ObjectError error : bindingResult.getAllErrors()) {
162+
sb.append('[').append(error).append("] ");
163+
}
164+
return sb.toString();
165+
}
166+
173167
}

spring-web/src/main/java/org/springframework/web/bind/support/WebExchangeBindException.java

Lines changed: 47 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -49,30 +49,67 @@ public class WebExchangeBindException extends ServerWebInputException implements
4949

5050

5151
public WebExchangeBindException(MethodParameter parameter, BindingResult bindingResult) {
52-
super("Validation failure", parameter, null, null, initMessageDetailArguments(bindingResult));
52+
super("Validation failure", parameter, null, null, null);
5353
this.bindingResult = bindingResult;
5454
getBody().setDetail("Invalid request content.");
5555
}
5656

57-
private static Object[] initMessageDetailArguments(BindingResult bindingResult) {
57+
58+
/**
59+
* Return the BindingResult that this BindException wraps.
60+
* <p>Will typically be a BeanPropertyBindingResult.
61+
* @see BeanPropertyBindingResult
62+
*/
63+
public final BindingResult getBindingResult() {
64+
return this.bindingResult;
65+
}
66+
67+
68+
@Override
69+
public Object[] getDetailMessageArguments() {
70+
return new Object[] {
71+
join(MethodArgumentNotValidException.errorsToStringList(getGlobalErrors())),
72+
join(MethodArgumentNotValidException.errorsToStringList(getFieldErrors()))};
73+
}
74+
75+
@Override
76+
public Object[] getDetailMessageArguments(MessageSource source, Locale locale) {
5877
return new Object[] {
59-
join(MethodArgumentNotValidException.errorsToStringList(bindingResult.getGlobalErrors())),
60-
join(MethodArgumentNotValidException.errorsToStringList(bindingResult.getFieldErrors()))};
78+
join(MethodArgumentNotValidException.errorsToStringList(getGlobalErrors(), source, locale)),
79+
join(MethodArgumentNotValidException.errorsToStringList(getFieldErrors(), source, locale))
80+
};
6181
}
6282

6383
private static String join(List<String> errors) {
6484
return String.join(", and ", errors);
6585
}
6686

6787
/**
68-
* Return the BindingResult that this BindException wraps.
69-
* <p>Will typically be a BeanPropertyBindingResult.
70-
* @see BeanPropertyBindingResult
88+
* Resolve global and field errors to messages with the given
89+
* {@link MessageSource} and {@link Locale}.
90+
* @return a Map with errors as key and resolves messages as value
91+
* @since 6.0.3
7192
*/
72-
public final BindingResult getBindingResult() {
73-
return this.bindingResult;
93+
public Map<ObjectError, String> resolveErrorMessages(MessageSource messageSource, Locale locale) {
94+
Map<ObjectError, String> map = new LinkedHashMap<>();
95+
addMessages(map, getGlobalErrors(), messageSource, locale);
96+
addMessages(map, getFieldErrors(), messageSource, locale);
97+
return map;
7498
}
7599

100+
private static void addMessages(
101+
Map<ObjectError, String> map, List<? extends ObjectError> errors,
102+
MessageSource messageSource, Locale locale) {
103+
104+
List<String> messages = MethodArgumentNotValidException.errorsToStringList(errors, messageSource, locale);
105+
for (int i = 0; i < errors.size(); i++) {
106+
map.put(errors.get(i), messages.get(i));
107+
}
108+
}
109+
110+
111+
// BindingResult implementation methods
112+
76113
@Override
77114
public String getObjectName() {
78115
return this.bindingResult.getObjectName();
@@ -285,6 +322,7 @@ public String[] getSuppressedFields() {
285322
return this.bindingResult.getSuppressedFields();
286323
}
287324

325+
288326
/**
289327
* Returns diagnostic information about the errors held in this object.
290328
*/
@@ -302,38 +340,6 @@ public String getMessage() {
302340
return sb.toString();
303341
}
304342

305-
@Override
306-
public Object[] getDetailMessageArguments(MessageSource source, Locale locale) {
307-
return new Object[] {
308-
join(MethodArgumentNotValidException.errorsToStringList(getGlobalErrors(), source, locale)),
309-
join(MethodArgumentNotValidException.errorsToStringList(getFieldErrors(), source, locale))
310-
};
311-
}
312-
313-
/**
314-
* Resolve global and field errors to messages with the given
315-
* {@link MessageSource} and {@link Locale}.
316-
* @return a Map with errors as key and resolves messages as value
317-
* @since 6.0.3
318-
*/
319-
public Map<ObjectError, String> resolveErrorMessages(MessageSource messageSource, Locale locale) {
320-
Map<ObjectError, String> map = new LinkedHashMap<>();
321-
addMessages(map, getGlobalErrors(), messageSource, locale);
322-
addMessages(map, getFieldErrors(), messageSource, locale);
323-
return map;
324-
}
325-
326-
private static void addMessages(
327-
Map<ObjectError, String> map, List<? extends ObjectError> errors,
328-
MessageSource messageSource, Locale locale) {
329-
330-
List<String> messages = MethodArgumentNotValidException.errorsToStringList(errors, messageSource, locale);
331-
for (int i = 0; i < errors.size(); i++) {
332-
map.put(errors.get(i), messages.get(i));
333-
}
334-
}
335-
336-
337343
@Override
338344
public boolean equals(@Nullable Object other) {
339345
return (this == other || this.bindingResult.equals(other));

0 commit comments

Comments
 (0)