Skip to content

Latest commit

 

History

History
199 lines (120 loc) · 6.04 KB

TIL220328.md

File metadata and controls

199 lines (120 loc) · 6.04 KB

Daily to do list

Java


Spring


CS


알고리즘


오늘의 회고

220328 Spring MVC

—————————————————

검증 Bean Validation

검증 코드를 항상 작성하는 것은 상당히 번거로운 일이다.

특히 특정 필드에 대한 검증 로직은 대부분 빈 값인지 아닌지 등 일반적이다.

그래서 이런 검증 로직을 애노테이션으로 만들어 본 것이다!

이런식으로…

이런 검증 로직을 모든 프로젝트에 적용할 수 있게 공통화 하고 표준화 한 것.

  • Bean Validation Bean Validation은 특정한 구현체가 아니라 자바에서 지원하는 기술 표준이다. 쉽게 이야기해서 검증 애노테이션과 여러 인터페이스의 모음이다.

Bean Validation을 구현한 기술 중 보편적인 것은 하이버네이트 Validation이다.

——————————— Bean Validation

스프링과 통합이 아닌 순수 Bean Validation

 Range는 하이버네이트에서만 지원 구현체 나머지는 표준 인터페이스

실행하면 애노테잇녀 기반의 Bean Validation이 정상 동작 함.. (@Validated를 자동으로..

@Validated, @valid가 있으면 글로벌 Validator를 등록함.

————————————————— 검증 순서

@ModelAttribute 각각의 필드에 타입 변환 시도

  1. 성공하면 다음으로
  2. 실패하면 typeMismatch로 FieldError 추가 Validator 적용
  • 바인딩에 성공한 필드만 Bean Validation 적용 BeanValidator는 바인딩에 실패한 필드는 BeanValidation을 적용하지 않는다. (일단 모델 객체에 바인딩 받는게 되어야 정사적인 검증이 의미가 있음)

@ModelAttribute >> 각각의 필드 타입 변환 시도 >> 변환에 성공한 필드만 BeanValidation 

—————————————————— Bean Validation - 에러 코드

 이러한 순서를 따라서 에러 코드를 properties에 저장할 수 재정의 할수도 있다.

——————————————————— 오브젝트 오류

이전까지는 필드 오류 였따..

이번에는 @ScriptAsset이다. 

이런식으로 적으면 된다. 객체에, 메시지도 추가 가능

실무에서는 사용하기는 사용하기 너무 제약이 많고 복잡하다.. 따라서 오브젝트(글로벌)오류의 경우 억지로 이걸 사용하기 보다는  그냥 이렇게 직접 컨트롤러에서 사용하는 것이 권장된다.

————————— Bean Validation - 수정에 적용

 @Validated와 BindingResult를 추가하고 객체 오류와 bindingREsult.hasError를 추가해주었다 그리고 editForm에서 태그들도 수정해줌

—————————————— Bean Validation 한계

 이렇게 바꾼다.. 하면 id는 등록 시 없어도 된다.. 뭐 이런 여러 사이드 이펙트가 발생함  ****참고로 이러한 것 신경도 써야함..

등록에서는 불가능하고 수정에서는 되는 이러한 문제..

Item객체가 등록 수정의 충돌이 발생.

이것을 해결하기 위해 Groups를 사용 ——————————————— Bean Validation - Groups

동일한 모델 객체를 등록할 떄와 수정할 때 각각 다르게 설정 가능.

방법 2가지

  • BeanValidation의 groups 기능
  • Item을 직접 사용하지 않고, ItemSaveForm,ItemUpdateForm 같은 폼 전송을 위한 별도의 모델 객체를 만들어서 사용

groups 적용

 그룹은 @Validated 애노테이션 안에 넣는다.

이런 그룹 기능은 @Validated만 있다!

  • 정리 근데… 그룹을 사용하니 Item의 복잡도가 엄청 올라갔다… 그래서 이것을 잘 사용하지 않는다 그리고 보통은 수정이랑 생성을 다르게 함 객체 자체도 달랒미..

—————————————— Form 전송 객체 분리

실무에서는 groups를 잘 사용하지 않는데 그 이유는 등록 시 폼에서 전달하는 데이터가 Item 도메인 객체와 딱 맞지 않기 때문이다. 실무에서는 Item과 관계없는 수 많으 부가 데이터도 넘어온다. 그래서 보통 Item을 직접 전달 ㅂ다는 것이 아니라 복잡한 폼 데이터를 컨트롤러까지 전달할 별도의 객체를 만들어서 전달한다.

거의 아래의 경우이다.. 복잡하게 오는 경우가 많다. 별도의 폼 객체를 만들어서 검증이 중복되지는 않음!

따라서 이렇게 폼 데이터 전달을 위한 별도의 객체를 사용하고, 등록, 수정용 폼 객체를 나누면 등록, 수정이 완전 분리

 이렇게 ItemSavaForm이라는 이름으로 하나 더 만들고

 따로 추가를 해서 주입

******* @Modelttribute(“item”)에 이름을 넣어주어야 함.. 안넣으면 규칙에 따라서 객체 이름이 바뀜

하이버네이트 Validator를 살펴보면 @Email등 다양하게 검증기능을 제공한다.

————————————————— Bean Validation - HTTP 메시지 컨버터

@Validated 는 HttpMessageConverter(“@RequestBody“)에도 적용이 가능하다.

**************** 진짜 중요참고 @ModelAttribute 는 Http 요청 파라미터(URL 쿼리 스트링, POST Form)를 다룰 떄!!! @RequestBody는 HTTP Body의 데이터를 객체로 변환할 때 사용한다. 주로 API JSON 요청을 다룰 떄 사용한다!

 메시지 바디에서는 컨트롤러를 호출하지 못하는 타입 에러같은 것은 실패 요청… 검증 오류는 quantity가 10000이상 이런 것

bindingresult.getAllErrors()는 객체, 필드 에러 둘 다 반환

@Modelattribute는 각각의 필드 단위로 세밀하게 적용 “그래서 특정 타입이 맞지 않아도 나머지 필드는 정상 처리”

하지만 @RequestBody는 필드 단위가 아닌 객체 단위 즉 “메시지 컨버터가 작동에 성공해야지 객체를 만들어야 @Validated가 적용”

참고 : HttpMessageConverter 단계에서 실패하면 예외가 발생한다.

——————————— 정리..