프로젝트에서 검증 시 에러필드의 정보를 클라이언트에 전달할 로직을 더욱 편하게 개선하는 방법에 대한 글을 작성해봅니다.
기존 'validation message'를 split하여 'field' 이름과 메시지를 분리하던 로직을 개선
@RestControllerAdvice
public class RestaurantControllerAdvice {
...
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
public SaveRestaurantResponseDto handleMethodArgumentNotValidation(MethodArgumentNotValidException e) {
return new SaveRestaurantResponseDto(getErrorData(e.getBindingResult()));
}
private Map<String, String> getErrorData(BindingResult bindingResult) {
Map<String, String> data = new HashMap<>();
bindingResult.getAllErrors()
.forEach(objectError -> {
String[] errorArray = objectError.getDefaultMessage().split(":");
if (isNeededFieldName(errorArray[0])) {
data.put(errorArray[0], errorArray[1]);
}
});
return data;
}
private boolean isNeededFieldName(String fieldName) {
return fieldName.equals("name") || fieldName.equals("minOrderPrice")
|| fieldName.equals("deliveryFee") || fieldName.equals("price")
|| fieldName.equals("quantity");
}
}
@NotNull(message = "name:음식명은 필수 입력 항목입니다")
@RestControllerAdvice
public class RestaurantControllerAdvice {
...
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
public RestaurantSaveResponseDto handleMethodArgumentNotValidation(MethodArgumentNotValidException e) {
return new RestaurantSaveResponseDto(getErrorData(e.getBindingResult()));
}
private Map<String, String> getErrorData(BindingResult bindingResult) {
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
Map<String, String> validation = new HashMap<>();
for (FieldError fieldError : fieldErrors) {
validation.put(getCorrectFieldName(fieldError.getField()), fieldError.getDefaultMessage());
}
return validation;
}
private String getCorrectFieldName(String field) {
if (field.contains(".")) {
String[] strings = field.split("\\.");
return strings[1];
}
return field;
}
}