-
bean validationTIL 2021. 3. 27. 22:45
여태 검증 로직은 내가 만들어 사용을 했었다.
유틸 클래스를 만들어 검증을 했었는데,
이번에 bean validation이라는 것을 알았다.
bean validation은 java bean에 대해 검증하는 명세라고 한다.
즉, 명세일 뿐, 실제로 사용을 하려면 구현체가 필요하다는 거다.
spring boot는 구현체 중 하나인 Hibernate Validator를 사용을 한다.
사용법을 알아보자.
1.
의존성 추가
2.
필요한 검증 어노테이션 추가.
Deprecated인데 그냥 쓰겠다.
hibernate 말고 javax 꺼(기본 제공 validation)를 쓰면 줄은 사라지긴 한다.
둘의 차이점도 있다.
isaac님이 알려주시기 전까지 같을 줄 알았는데,
javax의 notBlank와 NotEmpty는 DB에 not null 제약조건을 붙이지 않는다.
hibernate의 NotBlank는 not null DB에 제약조건을 붙인다.
즉, javax의 @NotBlank = "", " " (X) null (X)
javax의 @NotEmpty= "" (X) null (O)
javax의 @NotNull="", " " (O) null (X)
hibernate의 @NotBlank = "", " " (X) null (X) (근데 Deprecated 됐음)
참 헷갈리게 만들어 놨다..
isaac56.github.io/jpa/2021/03/31/JPA-NotBlank-NotEmpty-does-not-change-DDL.html
Dev.Isaac
@NotEmpty와 @NotBlank가 붙어도 NOT NULL 제약조건이 생성되지 않는다. 최근 validation을 테스트해보다가 알게 되었다. @NotNull은 하이버네이트가 자동으로 해석하여 table 생성 시 NOT NULL 제약조건을 생성
isaac56.github.io
3.
service에서 @Validated와 사용할 메서드에 @Valid를 붙이라는데 나는 안 붙여도 잘된다. 이유는 모르겠다.
그럼 이제 끝이다. form에서 넘어온 데이터를 db에 write 하기 전에 검사를 진행해 조건에 걸리면 exception이 발생한다.
(수정)
service가 아니라 controller에 적용해야 먹힌다.
controller에 valid 미적용시 controller에 valid 적용시 둘의 에러 문구가 다르다.
Entity에 조건을 넣고 에러가 발생하는 정보를 넣으면
@valid를 넣지 않으면 ConstraintViolationException을
controller에 @valid를 넣어서 에러시는 BindException을 : 치명적인 바인딩 오류
발생시킨다.
예상키로 ConstraintViolationException은 valid에 걸리지 않고 commit 되기 전에 하이버네이트가 검사할 때 Entity에 걸려있는 조건과 다를 경우 해당 예외를 발생시키고,
BindException은 컨트롤러로 들어올 때 검사를 진행해서 Entity에 걸려있는 조건과 다를 경우 발생시키는 것 같다.
MethodArgumentNotValidException : @Valid 주석이 달린 인수 가 유효성 검사에 실패하면이 예외가 throw 됩니다.
->ConstraintViolationException의 상위 예외
ConstraintViolationException예외는 패스벨리어블이나 리퀘스트 파람에서 예외가 나온다.
valid를 넣지 않으면 나오는 이유를 뒤늦게 알게 되었다.
https://jongmin92.github.io/2019/11/18/Spring/bean-validation-1/
Spring Boot에서의 Bean Validation (1)
Bean Validation은 Java 생태계에서 유효성(Validation) 검증 로직을 구현하기위한 사실상의 표준이다. Bean Validation은 Spring과 Spring Boot에도 잘 통합되어 있다.
jongmin92.github.io
JavaBean Validation과 Hibernate Validator 그리고 Spring Boot
이 글은 JavaBean Validation(이하 Bean Validation)의 기본 개념과 Hibernate Validator와의 관계 그리고 Spring Boot에서 간단한 사용법을 소개한다.
medium.com
에러 종류
velog.io/@soulkst/Spring-boot-error-handling
Spring boot error handling
Spring boot로 REST API 개발 시 요청 데이터 Validation을 위한 ControllerAdvice의 Exception HandlingRequest Body가 JSON이며, jackson json을 사용할 때 잘못된 JSON 포맷일 경우@Valid A
velog.io
다른 예외를 내는 이유
stackoverflow.com/questions/57010688/what-is-the-difference-between-constraintviolationexception-and-methodargumentnostackoverflow.com/questions/56467965/why-spring-boot-throws-different-exceptions-for-controller-method-argument-valid
What is the difference between ConstraintViolationException and MethodArgumentNotValidException
When I am validating bean using @valid annotation in javax.validations, for some objects I am getting ConstraintViolationException and for some I am getting MethodArgumentNotValidException. I unde...
stackoverflow.com
www.baeldung.com/global-error-handler-in-a-spring-rest-api
예외 설명
Custom Error Message Handling for REST API | Baeldung
Implement a Global Exception Handler for a REST API with Spring.
www.baeldung.com
그럼 service에서의 @valid는 왜 먹히지 않는 것 인가?
service는 그냥 빈을 뿐이고 controller는 HandlerMethodArgumentResolver를 이용해 바인딩해주는 역할까지 해주기 때문이다.
우리가 form으로 입력한 데이터가 어떻게 controller에서는 객체로 만들어져서 받을 수 있는 걸까?
HandlerMethodArgumentResolver가 바인딩을 해주기 때문이다.
바인딩해주는 작업을 하면서 유효성 검사까지 하는 것이다.
stackoverflow.com/questions/63618897/service-layer-bean-validation-in-spring-5
Service layer bean validation in Spring 5?
I need to validate beans given as argument to service layer methods in a Spring 5 application. I can get validation to work on controllers but on service layer the @Valid annotation is ignored. The
stackoverflow.com
@Notnull과@Column (nullable = false)의 차이점
hibernate의 notNull은 테이블을 만들 때 제약조건을 추가해준다.
application.properties에 다음을 추가하면 db에 제약조건을 추가하지 않는다.
spring.jpa.properties.hibernate.validator.apply_to_ddl=false
db에 제약 조건이 없음에도 조건을 위배하면 예외가 발생한다. insert문은 나가지 않는다.
즉 , 검증을 db가 하는 게 아닌 hibernate가 검증을 진행한다는 거다.
이게 좋다.
그럼 @Column (nullable = false)은 어떨까?
똑같이 db에 제약조건이 추가된다.
하지만 write 할 때 null을 주고 넘기면 db에서 예외가 발생한다.
즉, 검증을 db에서 한다는 거다. 제약조건을 통해.
그러니까 전자를 사용하는 게 더 좋다 이 말이다.
www.baeldung.com/hibernate-notnull-vs-nullable
Hibernate @NotNull vs @Column(nullable = false) | Baeldung
A quick and practical overview of @NotNull and @Column(nullable = false) in Java.
www.baeldung.com
'TIL' 카테고리의 다른 글
URL convention (0) 2021.03.28 2021.03.28 기록장 (0) 2021.03.27 2021.03.27 기록장 (0) 2021.03.27 2021.03.26 기록장 (0) 2021.03.25 2021.03.25 기록장 (0) 2021.03.24