검증 애노테이션 모음 한번 읽어보자
@Validated가 있으면 글로벌 Validator가 실행되면서 Item을 딱보니까 @NotNull 과 같은 애노테이션이 있구나 하고 검증을 함
검증한 결과를 BindingResult에 담음
price 필드는 BeanValidation 적용 X
errors.properties의
#추가
typeMismatch.java.lang.Integer=숫자를 입력해주세요.
가 적용된것.
HTML Form -> Item -> Controller -> Item -> Repository
Html폼에서 Item을 그대로 쓰고, Controller에서 Item을 그대로 쓰고,
Repository에 그대로 넘긴다.
(내 이해: Item 객체를 바인딩한 것이 컨트롤러에 넘어가고 컨트롤러에서는 이 Item에 직접 접근한다.)
HTML Form -> ItemSaveForm -> Controller -> Item 생성 -> Repository
HTML 폼이 입력되면 ItemSaveForm에서 @ModelAttribute를 받는다. 이게 컨트롤러로 넘어가고 컨트롤러에서는 필요하면 아이템을 생성한다그 후 이걸 리포지토리에 넣는다
Q: 이름은 어떻게 지어야 하나요?
이름은 의미있게 지으면 된다. ItemSave 라고 해도 되고, ItemSaveForm , ItemSaveRequest ,ItemSaveDto 등으로 사용해도 된다. 중요한 것은 일관성이다.
강사님 : form에서 넘어올 때 -> ItemSaveForm
API에서 넘어올 때 -> 요청같은 경우 ItemSaveRequest
폼은 web하위 폴더에 만들거다
왜? HTML 폼의 데이터를 내가 그대로 받기 때문에 컨트롤러 레벨까지만 받을거다. 다른 곳에서는 사용되지 않게~
@PostMapping("/add")
public String addItem2(@Validated @ModelAttribute ItemSaveForm form,
이렇게 되면 model.addAttribute("itemSaveForm)으로 담긴다.(객체명이름으로 들어감. 첫글자를 소문자로 바꿔서)
html 수정하기 번거로우니까 @ModelAttribute("item") ItemSaveForm form 으로 해준다
ItemRepository는 Item을 받기 때문에
Item객체를 생성해서 값을 넣어준다.
API로 데이터 왔다갔다할 때, Bean Validation이 어떻게 적용되는지 알아보자.
@Valid , @Validated 는 HttpMessageConverter ( @RequestBody )에도 적용할 수 있다.
참고
@ModelAttribute 는 HTTP 요청 파라미터(URL 쿼리 스트링, POST Form)를 다룰 때 사용한다.
@RequestBody(HttpMessageConverter가 동작) 는 HTTP Body의 데이터를 객체로 변환할 때 사용한다. 주로 API JSON 요청을 다룰 때
사용한다.
json이 ItemSaveForm 객체로 바뀌어야 그 다음에 Validation할 수 있는데, HttpMessageConverter가 ItemSaveForm 객체를 만들어야 컨트롤러 호출할 수 있다. 이 객체를 못만들어서 실패함
HttpMessageConverter가 @RequestBody보고 ItemSaveForm 너 Json이네 파싱해서 만들어줄게 했는데 이게 안된것
API의 경우 3가지 경우를 나누어 생각해야 한다.
성공 요청: 성공
실패 요청: JSON을 객체로 생성하는 것 자체가 실패함(HttpMessageConverter 자체에서 실패)
검증 오류 요청: JSON을 객체로 생성하는 것은 성공했고, 검증에서 실패함