2. @ModelAttribute
ModelAttribute 어노테이션은 Model에 data를 자동으로 저장한다. 매개변수, 반환 타입에 적용할 수 있다.
mian 메서드의 매개변수에 @ModelAttribute MyDate date를 적으면 m.addAttribute("myDate", date);를 적지 않아도 된다. 자동으로 Model 객체에 key, value인 map 형태로 key값인 "myDate"에 value로 date의 주소가 들어간다. @ModelAttribute("myDate") MyDate date에 key값을 적지 않으면 변수 타입의 첫 글자를 소문자로 바꿔서 key로 사용한다. 즉 @ModelAttribute MyDate date에서 Mydate의 첫 글자를 소문자로 바꾼 myDate를 key로 사용한다.
반환 타입에도 ModelAttribute 어노테이션 사용 할 수 있다. getYoil 메서드의 호출 결과를 Model에 자동으로 담는다. "yoil"이 key 값이다. getYoil 메서드의 결과가 '수'이면 "yoil"인 key에 value로 '수'가 저장된다. 따라서 main 메서드에서 yoil을 호출하고 저장하는 코드를 제거할 수 있다. Spring 내부에서 Controller에 붙은 @ModelAttribute 부분을 전부 호출해서 Model에 저장한다. 따라서 호출, 저장하는 코드를 쓸 필요가 없다.
반환 타입에 ModelAttribute 어노테이션을 사용할 때는 key 값을 반드시 입력해야 한다. ModelAttribute 어노테이션을 이용하면 2. 처리, 3. Model에 작업 결과 저장 코드를 쓰지 않아도 된다.
출력 결과
참조형의 ModelAttribute은 생략 가능하다. 컨트롤러 매개변수에 붙을 수 있는 어노테이션이 @RequestParam, @ModelAttribute 2개가 있다. 매개 변수가 참조형 일 때 @ModelAttribute이 생략되어있고, 기본형, String 일 때는 @RequestParam이 생략되었다고 볼 수 있다. 참조형은 값이 여러개이므로 @RequestParam을 붙일 수 없다. 기본형, String은 jsp파일에서 ${param.파라미터이름}으로 바로 사용할 수 있어 Model에 저장하지 않아도 된다. 따라서 @ModelAttribute를 쓸 필요가 없다.
3. WebDataBinder
컨트롤러 메서드를 url로 호출했을 때, Query String의 data가 map 형태로 구성된다. 이 값이 컨트롤러 메서드에 전달될 때 값을 받는 매개 변수 타입이 MyDate이다.
MyDate 타입의 객체가 만들어지고 위와 값 2021, 10, 1이 담긴다. 이 때 map의 value는 String이고 MyDate에 담긴 것은 int이므로 중간에 형변환이 이뤄진다. 변환을 해주는 것이 WebDataBinder이다. WebDataBinder가 하는 일이 첫 번째로 타입 변환을 하고 그 다음에 데이터 검증을 한다.
타입 변환을 하면 그 결과, 에러를 BindingResult에 저장한다. 데이터 검증은 Validation이라 하고 month의 범위는 1~12가 가능하므로 이를 걸러내는 작업을 한다. 데이터 검증을 한 결과, 에러 또한 BindingResult에 저장한다. BindingResult를 Controller에게 넘기고 결과를 처리한다.
BindingResult result는 Binding할 객체인 My date바로 뒤에 와야한다. DataBinder는 브라우저의 요청을 받아올 때 중간 역할인 타입 변환, 데이터 검증을 하고 결과와 에러를 BindingResult에 저장한다.
Controller를 위와 같이 BindingResult를 쓰고 url의 day값에 올바르지 않는 값을 준다. 예외 처리 때문에 yoilError.jsp가 호출되어 예외 처리문을 주석 처리하고 다시 실행한다.
⭐ url에 day=1을 입력해도 yoilError.jsp가 호출되는데, 카페에 라고 답변을 달아주셨는데 잘 몰?루 겠음. |
예외 처리를 주석처리하고 url을 재실행하면 BindingResult에 에러가 1개 있다고 나온다. System.out.println("result="+result);을 찍어서 console에서 result가 찍혔는지 찾아봐도 나오지 않는데 발생한 에러가 Controller까지도 가지 않았다.
예외 처리를 주석 해제하고 매개변수에 BindingResult을 추가하고 System.out.println("result="+result);를 찍어본다.
예외 처리가 실행되었고 console에 result가 어떻게 출력되었는지 확인하자.
result에 BindingResult 에러가 1개 있다고 출력되었고 내용은 필드 'day'의 'myDate' 객체에 [aa]가 거절되었다.
위와 같이 예외 처리에 코드를 추가하면 error의 정보를 더 얻을 수 있다.
'스프링의 정석 > Ch. 02 Spring MVC' 카테고리의 다른 글
20. @GetMapping, @PostMapping (1) (0) | 2023.07.25 |
---|---|
19. 회원가입 화면 작성하기 (0) | 2023.07.22 |
17. @RequestParam과 @ModelAttribute (0) | 2023.07.19 |
16. 서블릿과 JSP (4) (0) | 2023.07.19 |
15. 서블릿과 JSP (3) (0) | 2023.07.15 |