반응형
기본 예제
Dependency
- maven
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
- gradle
dependencies {
...
implementation 'org.springframework.boot:spring-boot-starter-validation'
}
Response
@Builder
@Getter
public class Response<T> {
private Status status;
private T body;
public enum Status {
SUCCESS,
NOT_VALID_REQUEST
}
}
ExceptionControllerAdvice
@RestControllerAdvice
public class ExceptionControllerAdvice {
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Response<List<String>> notValidException(MethodArgumentNotValidException exception) {
return Response.<List<String>>builder()
.status(Response.Status.NOT_VALID_REQUEST)
.body(exception.getBindingResult()
.getFieldErrors()
.stream()
.map(fieldError -> fieldError.getField() + " : " + fieldError.getDefaultMessage())
.collect(Collectors.toList()))
.build();
}
}
SaveTodoParams
@Data
public class SaveTodoParams {
@NotEmpty
private String todoId;
@NotEmpty
private String title;
@Valid // 하위 객체도 유효성 체크가 필요할 경우 달아줘야함
@NotEmpty
private List<TodoItem> todoItems;
@Data
public static class TodoItem {
@NotEmpty
private String itemId;
@NotEmpty
private String contents;
@NotNull
@Min(1)
private Integer order;
}
}
TodoController
@Slf4j
@RestController
public class TodoController {
@PostMapping("/api/todos")
public void saveTodos(@Valid @RequestBody SaveTodoParams params) { // 유효성 체크를 위해 @Valid 추가 필요
log.info("params : {}", params);
}
}
요청
curl --location --request POST 'http://localhost:8080/api/todos' \
--header 'Content-Type: application/json' \
--data-raw '{
"todoId": null,
"title": null,
"todoItems": [
{
"itemId": null,
"contents": null,
"order": 0
}
]
}'
응답
{
"status": "NOT_VALID_REQUEST",
"body": [
"todoItems[0].contents : 비어 있을 수 없습니다",
"todoId : 비어 있을 수 없습니다",
"todoItems[0].itemId : 비어 있을 수 없습니다",
"todoItems[0].order : 1 이상이어야 합니다",
"title : 비어 있을 수 없습니다"
]
}
Custom Validation
DateTimePattern
@Documented
@Constraint(validatedBy = DateTimePatternValidator.class)
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface DateTimePattern {
String value() default "yyyy-MM-dd HH:mm:ss";
String message() default "유효한 포맷 - {value}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
DateTimePatternValidator
public class DateTimePatternValidator implements ConstraintValidator<DateTimePattern, String> {
private DateTimePattern dateTimePattern;
@Override
public void initialize(DateTimePattern dateTimePattern) {
this.dateTimePattern = dateTimePattern;
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (value == null || value.isEmpty()) {
return true;
}
try {
LocalDateTime.parse(value, DateTimeFormatter.ofPattern(dateTimePattern.value()));
} catch (DateTimeParseException e) {
return false;
}
return true;
}
}
DemoParams
@Data
public class DemoParams {
@NotEmpty
@DateTimePattern("yyyy.MM.dd HH.mm")
private String date;
}
DemoController
@Slf4j
@RestController
public class DemoController {
@PostMapping("/api/demo")
public void demo(@Valid @RequestBody DemoParams params) {
log.info("params : {}", params);
}
}
요청
curl --location --request POST 'http://localhost:8080/api/demo' \
--header 'Content-Type: application/json' \
--data-raw '{
"date": "2021-12-31 23:59:59"
}'
응답
{
"status": "NOT_VALID_REQUEST",
"body": [
"date : 유효한 포맷 - yyyy.MM.dd HH.mm"
]
}
반응형
'Development > Spring' 카테고리의 다른 글
[Spring] Argument Resolver (0) | 2020.12.27 |
---|---|
[Spring] Filter & Interceptor (0) | 2020.12.27 |
[Spring] BeanFactory & ApplicationContext (0) | 2020.12.27 |
[Spring] Paging (0) | 2020.12.27 |
[Spring] FileDownload (0) | 2020.12.27 |