Reputation: 4691
Need some helps to convert this loop using Stream API :
protected ResponseEntity<Object> handleMethodArgumentNotValid( MethodArgumentNotValidException ex,
HttpHeaders headers, HttpStatus status, WebRequest request ) {
Map<String, Set<String>> fieldErrorWithMessages = new HashMap<String, Set<String>>();
List<FieldError> fieldErrors = ex.getBindingResult().getFieldErrors();
Set<String> messages;
for ( FieldError error : fieldErrors ) {
String currentField = error.getField();
String currentErrorMessage = message.getMessage( error.getCodes()[0], null, locale );
if ( !fieldErrorWithMessages.containsKey( currentField ) ) {
messages = new HashSet<String>();
messages.add( currentErrorMessage );
fieldErrorWithMessages.put( currentField, messages );
} else {
if ( !fieldErrorWithMessages.get( currentField ).contains( currentErrorMessage ) ) {
fieldErrorWithMessages.get( currentField ).add( currentErrorMessage );
}
}
}
.....
}
The goal is to group each field with its error messages. The error messages are stored in a message.properties
file. This code works as expected but I would like to know if I can make it more concise using Stream API. Something like :
Map<String, Set<String>> fieldErrorWithMessages =fieldErrors.stream().collect( Collectors.groupingBy( FieldError::getField,/*something returnig a set of messages stored in messages.properties for each field*/ ) );
Note that to retrieve the message I use the first code of FieldError.getCodes()
, see above : error.getCodes()[0]
Thanks
Upvotes: 3
Views: 567
Reputation: 34460
This is a complement to @shmosel's answer. As it's been written there, the original code can be significantly improved before attempting to use streams. Here's a way:
protected ResponseEntity<Object> handleMethodArgumentNotValid(
MethodArgumentNotValidException ex,
HttpHeaders headers,
HttpStatus status,
WebRequest request) {
Map<String, Set<String>> fieldErrorWithMessages = new HashMap<>();
ex.getBindingResult().getFieldErrors().forEach(error ->
fieldErrorWithMessages.computeIfAbsent(
error.getField(),
k -> new HashSet<>())
.add(message.getMessage(error.getCodes()[0], null, locale)));
// .....
}
Upvotes: 0
Reputation: 50716
There's actually significant room to cut that down without streams, but I'll cut to the chase:
Map<String, Set<String>> fieldErrorWithMessages = ex.getBindingResult()
.getFieldErrors()
.stream()
.collect(Collectors.groupingBy(
FieldError::getField,
Collectors.mapping(
error -> message.getMessage(error.getCodes()[0], null, locale),
Collectors.toSet())));
Upvotes: 4