ArgumentResolver 적용전을 대상으로 한다.
인터셉터 : 특정 URI로 요청시 Controller로 가는 요청을 가로채는 역할을 한다.
스프링 인터셉터 호출 흐름
정상 흐름
preHandle
: 컨트롤러 호출 전에 호출된다. (더 정확히는 핸들러 어댑터 호출 전에 호출된다.) preHandle
의 응답값이 true
이면 다음으로 진행하고, false
이면 더는 진행하지 않는다. false
인 경우 나머지 인터셉터는 물론이고, 핸들러 어댑터도 호출되지 않는다. 그림에서 1번에서 끝이 나버린다.postHandle
: 컨트롤러 호출 후에 호출된다. (더 정확히는 핸들러 어댑터 호출 후에 호출된다.) afterCompletion
: 뷰가 렌더링 된 이후에 호출된다.
스프링 인터셉터 예외 상황
예외가 발생시
preHandle
: 컨트롤러 호출 전에 호출된다.postHandle
: 컨트롤러에서 예외가 발생하면 postHandle
은 호출되지 않는다.afterCompletion
: afterCompletion
은 항상 호출된다. 이 경우 예외( ex
)를 파라미터로 받아서 어떤 예외가 발생했는지 로그로 출력할 수 있다.
WebConfig - 인터셉터 등록
LogInterceptor
를 실행한다.
실행했을 때 전체적인 log 출력 내용
h.login.web.interceptor.LogInterceptor : LogInterceptor REQUEST [e725f1cc-7508-4e39-9d2a-9183f6f70096][/][hello.login.web.HomeController#homeLoginV3Spring(Member, Model)]
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="home"; model={}]]
h.login.web.interceptor.LogInterceptor : LogInterceptor RESPONSE [e725f1cc-7508-4e39-9d2a-9183f6f70096][/][hello.login.web.HomeController#homeLoginV3Spring(Member, Model)]
LogInterceptor
클래스에서 preHandle
, postHandle
, afterCompletion
실행 결과이다.preHandle
, postHandle
, afterCompletion
는 HandlerInterceptor
인터페이스로부터 상속받아 구현하였다.
preHandle
: 컨트롤러 호출 전
h.login.web.interceptor.LogInterceptor : LogInterceptor REQUEST [e725f1cc-7508-4e39-9d2a-9183f6f70096][/][hello.login.web.HomeController#homeLoginV3Spring(Member, Model)]
부터 보면,
hello.login.web.HomeController#homeLoginV3Spring(Member, Model)
를 실행한다.
@SessionAttribute(name = SessionConst.LOGIN_MEMBER, required = false) Member loginMember, Model model
// 이미 로그인한 사용자가 있는지 찾는다.
// 이 기능은 세션을 생성하지 않는다.
여기서 SessionConst.LOGIN_MEMBER
는
이다!
✏️ preHandle 실행 정리
- 세션에 회원 데이터가 없으면 home으로 이동한다.
- 세션이 유지되면 로그인으로 이동한다.
postHandle
: 컨트롤러 호출 후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="home"; model={}]]
부터 보면 LogInterceptor postHandle [ModelAndView [view="home"; model={}]]
를 실행한다.
afterCompletion
: 뷰가 렌더링 된 이후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor RESPONSE [e725f1cc-7508-4e39-9d2a-9183f6f70096][/][hello.login.web.HomeController#homeLoginV3Spring(Member, Model)]
부터 보면 hello.login.web.HomeController#homeLoginV3Spring(Member, Model)
를 실행하는데 이는 요청 완료된 이후 실행되는 결과이다.
✏️ preHandle, postHandle, afterCompletion 실행 정리
컨트롤러 호출 전에preHandle
을 실행한다.
컨트롤러 호출 후에postHandle
을 실행한다. (예외 발생시 호출하지 않는다.)
뷰가 렌더링 된 이후에afterCompletion
호출된다.
실행했을 때 전체적인 log 출력 내용
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [d06f4567-8f98-4b7e-bb72-f40404f44117][/members/add][hello.login.web.member.MemberController#addForm(Member)]
hello.login.web.member.MemberController : input member=Member(id=null, loginId=null, name=null, password=null)
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="members/addMemberForm"; model={member=Member(id=null, loginId=null, name=null, password=null), org.springframework.validation.BindingResult.member=org.springframework.validation.BeanPropertyBindingResult: 0 errors}]]
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [d06f4567-8f98-4b7e-bb72-f40404f44117][/members/add][hello.login.web.member.MemberController#addForm(Member)]
LogInterceptor
클래스에서 preHandle
, postHandle
, afterCompletion
실행 결과이다.
preHandle
: 컨트롤러 호출 전
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [d06f4567-8f98-4b7e-bb72-f40404f44117][/members/add][hello.login.web.member.MemberController#addForm(Member)]
hello.login.web.member.MemberController#addForm(Member)
를 실행한다.
input member={}
가 로그에 출력된다.templates/members/addMemberForm
회원가입 html
화면을 띄워준다.
templates/members/addMemberForm
postHandle
: 컨트롤러 호출 후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="members/addMemberForm"; model={member=Member(id=null, loginId=null, name=null, password=null), org.springframework.validation.BindingResult.member=org.springframework.validation.BeanPropertyBindingResult: 0 errors}]]
addMemberForm
을 기준으로 현재 입력된 값이 없기 때문에 validation.BindingResult가 실행된다.
afterCompletion
: 뷰가 렌더링 된 이후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [d06f4567-8f98-4b7e-bb72-f40404f44117][/members/add][hello.login.web.member.MemberController#addForm(Member)]
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [0d5564f4-e550-468d-b29f-4957b4881002][/members/add][hello.login.web.member.MemberController#save(Member, BindingResult)]
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="redirect:/"; model={}]]
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [0d5564f4-e550-468d-b29f-4957b4881002][/members/add][hello.login.web.member.MemberController#save(Member, BindingResult)]
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [73844fc4-6899-4457-bd6d-f40a5fa8250d][/][hello.login.web.HomeController#homeLoginV3Spring(Member, Model)]
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="home"; model={}]]
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [73844fc4-6899-4457-bd6d-f40a5fa8250d][/][hello.login.web.HomeController#homeLoginV3Spring(Member, Model)]
preHandle
: 컨트롤러 호출 전
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [0d5564f4-e550-468d-b29f-4957b4881002][/members/add][hello.login.web.member.MemberController#save(Member, BindingResult)]
hello.login.web.member.MemberController#save(Member, BindingResult)
를 실행한다.
postHandle
: 컨트롤러 호출 후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="redirect:/"; model={}]]
afterCompletion
: 뷰가 렌더링 된 이후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [0d5564f4-e550-468d-b29f-4957b4881002][/members/add][hello.login.web.member.MemberController#save(Member, BindingResult)]
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [73844fc4-6899-4457-bd6d-f40a5fa8250d][/][hello.login.web.HomeController#homeLoginV3Spring(Member, Model)]
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="home"; model={}]]
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [73844fc4-6899-4457-bd6d-f40a5fa8250d][/][hello.login.web.HomeController#homeLoginV3Spring(Member, Model)]
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [0b17592d-eaf7-41a3-89e0-4f6ca9913cc6][/login][hello.login.web.login.LoginController#loginForm(LoginForm)]
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="login/loginForm"; model={loginForm=LoginForm(loginId=null, password=null), org.springframework.validation.BindingResult.loginForm=org.springframework.validation.BeanPropertyBindingResult: 0 errors}]]
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [0b17592d-eaf7-41a3-89e0-4f6ca9913cc6][/login][hello.login.web.login.LoginController#loginForm(LoginForm)]
preHandle
: 컨트롤러 호출 전
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [0b17592d-eaf7-41a3-89e0-4f6ca9913cc6][/login][hello.login.web.login.LoginController#loginForm(LoginForm)]
hello.login.web.login.LoginController#loginForm(LoginForm)
를 실행한다.
LoginController
LoginForm 클래스
template/login/loginForm
실행
postHandle
: 컨트롤러 호출 후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="login/loginForm"; model={loginForm=LoginForm(loginId=null, password=null), org.springframework.validation.BindingResult.loginForm=org.springframework.validation.BeanPropertyBindingResult: 0 errors}]]
afterCompletion
: 뷰가 렌더링 된 이후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [0b17592d-eaf7-41a3-89e0-4f6ca9913cc6][/login][hello.login.web.login.LoginController#loginForm(LoginForm)]
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [04de1c46-26db-4e61-b0a6-348193f03d57][/login][hello.login.web.login.LoginController#loginV4(LoginForm, BindingResult, String, HttpServletRequest)]
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="login/loginForm"; model={loginForm=LoginForm(loginId=test, password=test), org.springframework.validation.BindingResult.loginForm=org.springframework.validation.BeanPropertyBindingResult: 1 errors
Error in object 'loginForm': codes [loginFail.loginForm,loginFail]; arguments []; default message [아이디 또는 비밀번호가 맞지 않습니다.]}]]
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [04de1c46-26db-4e61-b0a6-348193f03d57][/login][hello.login.web.login.LoginController#loginV4(LoginForm, BindingResult, String, HttpServletRequest)]
preHandle
: 컨트롤러 호출 전
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [04de1c46-26db-4e61-b0a6-348193f03d57][/login][hello.login.web.login.LoginController#loginV4(LoginForm, BindingResult, String, HttpServletRequest)]
hello.login.web.login.LoginController#loginV4(LoginForm, BindingResult, String, HttpServletRequest)
가 실행된다.
@Valid @ModelAttribute LoginForm form
에 값이 담겨있다.
id
, password
를 입력했으므로 세션이 실행되지 않고 위에서 끝난다.HttpSession session = request.getSession();
// 세션에 로그인 회원 정보 보관
session.setAttribute(SessionConst.LOGIN_MEMBER, loginMember);
request.getSession();
session.setAttribute(SessionConst.LOGIN_MEMBER, loginMember);
return "redirect:" + redirectURL;
postHandle
: 컨트롤러 호출 후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="login/loginForm"; model={loginForm=LoginForm(loginId=test, password=test), org.springframework.validation.BindingResult.loginForm=org.springframework.validation.BeanPropertyBindingResult: 1 errors
Error in object 'loginForm': codes [loginFail.loginForm,loginFail]; arguments []; default message [아이디 또는 비밀번호가 맞지 않습니다.]}]]
id
와 password
를 확인해보니, 검증 결과 error가 발생한다.
위 preHandle
에서 설명한 loginV4
를 확인시 쉽게 알 수 있다.
if (loginMember == null) {
bindingResult.reject("loginFail", "아이디 또는 비밀번호가 맞지 않습니다.");
return "login/loginForm";
}
가 실행되어 다시 로그인 화면으로 이동한다.
afterCompletion
: 뷰가 렌더링 된 이후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [04de1c46-26db-4e61-b0a6-348193f03d57][/login][hello.login.web.login.LoginController#loginV4(LoginForm, BindingResult, String, HttpServletRequest)]
첫 로그인시, 주소에 세션 id가 출력된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [9c6c80a6-cd9d-4ad4-ab2e-492f25a259c9][/login][hello.login.web.login.LoginController#loginV4(LoginForm, BindingResult, String, HttpServletRequest)]
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="redirect:/"; model={}]]
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [9c6c80a6-cd9d-4ad4-ab2e-492f25a259c9][/login][hello.login.web.login.LoginController#loginV4(LoginForm, BindingResult, String, HttpServletRequest)]
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [c41ecf9d-b75d-4193-8a8b-7a4c179d60c0][/][hello.login.web.HomeController#homeLoginV3Spring(Member, Model)]
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="loginHome"; model={member=Member(id=1, loginId=test, name=테스트, password=test!), org.springframework.validation.BindingResult.member=org.springframework.validation.BeanPropertyBindingResult: 0 errors}]]
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [c41ecf9d-b75d-4193-8a8b-7a4c179d60c0][/][hello.login.web.HomeController#homeLoginV3Spring(Member, Model)]
preHandle
: 컨트롤러 호출 전
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [9c6c80a6-cd9d-4ad4-ab2e-492f25a259c9][/login][hello.login.web.login.LoginController#loginV4(LoginForm, BindingResult, String, HttpServletRequest)]
hello.login.web.login.LoginController#loginV4(LoginForm, BindingResult, String, HttpServletRequest)
가 실행된다.
@Valid @ModelAttribute LoginForm form
에 값이 담겨있다.)
HttpSession session = request.getSession();
// 세션에 로그인 회원 정보 보관
session.setAttribute(SessionConst.LOGIN_MEMBER, loginMember);
request.getSession();
session.setAttribute(SessionConst.LOGIN_MEMBER, loginMember);
return "redirect:" + redirectURL;
postHandle
: 컨트롤러 호출 후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="redirect:/"; model={}]]
afterCompletion
: 뷰가 렌더링 된 이후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [9c6c80a6-cd9d-4ad4-ab2e-492f25a259c9][/login][hello.login.web.login.LoginController#loginV4(LoginForm, BindingResult, String, HttpServletRequest)]
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [c41ecf9d-b75d-4193-8a8b-7a4c179d60c0][/][hello.login.web.HomeController#homeLoginV3Spring(Member, Model)]
homeLoginV3Spring
클래스를 상으로 컨트롤러 호출 전 세팅을 한다.
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="loginHome"; model={member=Member(id=1, loginId=test, name=테스트, password=test!), org.springframework.validation.BindingResult.member=org.springframework.validation.BeanPropertyBindingResult: 0 errors}]]
loginHome
이 실행 된다.
templates/loginHome
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [c41ecf9d-b75d-4193-8a8b-7a4c179d60c0][/][hello.login.web.HomeController#homeLoginV3Spring(Member, Model)]
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [a8c9d14d-8bcf-4512-8e7b-1c268a58728c][/items][hello.login.web.item.ItemController#items(Model)]
h.l.w.interceptor.LoginCheckInterceptor : 인증 체크 인터셉터 실행 /items
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="items/items"; model={items=[Item(id=1, itemName=itemA, price=10000, quantity=10), Item(id=2, itemName=itemB, price=20000, quantity=20)]}]]
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [a8c9d14d-8bcf-4512-8e7b-1c268a58728c][/items][hello.login.web.item.ItemController#items(Model)]
preHandle
: 컨트롤러 호출 전
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [a8c9d14d-8bcf-4512-8e7b-1c268a58728c][/items][hello.login.web.item.ItemController#items(Model)]
hello.login.web.item.ItemController#items(Model)
을 실행된다.
itemRepository
에 있는 모든 아이템들을 model
에 추가한다.
templates/items/items
h.l.w.interceptor.LoginCheckInterceptor : 인증 체크 인터셉터 실행 /items
입력한 내용들을 검증한다. (추가 알게 되면 수정하기)
postHandle
: 컨트롤러 호출 후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="items/items"; model={items=[Item(id=1, itemName=itemA, price=10000, quantity=10), Item(id=2, itemName=itemB, price=20000, quantity=20)]}]]
items/items
에 아이템 2개를 띄워준다.
afterCompletion
: 뷰가 렌더링 된 이후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [a8c9d14d-8bcf-4512-8e7b-1c268a58728c][/items][hello.login.web.item.ItemController#items(Model)]
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [d4d83c88-40b2-48dd-99b0-739fce6c25f5][/items/add][hello.login.web.item.ItemController#addForm(Model)]
h.l.w.interceptor.LoginCheckInterceptor : 인증 체크 인터셉터 실행 /items/add
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="items/addForm"; model={item=Item(id=null, itemName=null, price=null, quantity=null), org.springframework.validation.BindingResult.item=org.springframework.validation.BeanPropertyBindingResult: 0 errors}]]
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [d4d83c88-40b2-48dd-99b0-739fce6c25f5][/items/add][hello.login.web.item.ItemController#addForm(Model)]
preHandle
: 컨트롤러 호출 전
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [d4d83c88-40b2-48dd-99b0-739fce6c25f5][/items/add][hello.login.web.item.ItemController#addForm(Model)]
hello.login.web.item.ItemController#addForm(Model)
이 실행된다.
templates/items/addForm
h.l.w.interceptor.LoginCheckInterceptor : 인증 체크 인터셉터 실행 /items
입력한 내용들을 검증한다. (추가 알게 되면 수정하기)
postHandle
: 컨트롤러 호출 후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="items/addForm"; model={item=Item(id=null, itemName=null, price=null, quantity=null), org.springframework.validation.BindingResult.item=org.springframework.validation.BeanPropertyBindingResult: 0 errors}]]
null
이다.
afterCompletion
: 뷰가 렌더링 된 이후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [d4d83c88-40b2-48dd-99b0-739fce6c25f5][/items/add][hello.login.web.item.ItemController#addForm(Model)]
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [74a14543-e8fb-4bb7-ad5f-2747a1ed7aab][/items/add][hello.login.web.item.ItemController#addItem(ItemSaveForm, BindingResult, RedirectAttributes)]
h.l.w.interceptor.LoginCheckInterceptor : 인증 체크 인터셉터 실행 /items/add
hello.login.web.item.ItemController : errors=org.springframework.validation.BeanPropertyBindingResult: 2 errors
Field error in object 'item' on field 'quantity': rejected value [111111]; codes [Max.item.quantity,Max.quantity,Max.java.lang.Integer,Max]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [item.quantity,quantity]; arguments []; default message [quantity],9999]; default message [9999 이하여야 합니다]
Field error in object 'item' on field 'price': rejected value [12]; codes [Range.item.price,Range.price,Range.java.lang.Integer,Range]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [item.price,price]; arguments []; default message [price],1000000,1000]; default message [1000에서 1000000 사이여야 합니다]
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="items/addForm"; model={item=ItemSaveForm(itemName=itemA, price=12, quantity=111111), org.springframework.validation.BindingResult.item=org.springframework.validation.BeanPropertyBindingResult: 2 errors
Field error in object 'item' on field 'quantity': rejected value [111111]; codes [Max.item.quantity,Max.quantity,Max.java.lang.Integer,Max]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [item.quantity,quantity]; arguments []; default message [quantity],9999]; default message [9999 이하여야 합니다]
Field error in object 'item' on field 'price': rejected value [12]; codes [Range.item.price,Range.price,Range.java.lang.Integer,Range]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [item.price,price]; arguments []; default message [price],1000000,1000]; default message [1000에서 1000000 사이여야 합니다]}]]
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [74a14543-e8fb-4bb7-ad5f-2747a1ed7aab][/items/add][hello.login.web.item.ItemController#addItem(ItemSaveForm, BindingResult, RedirectAttributes)]
preHandle
: 컨트롤러 호출 전
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [74a14543-e8fb-4bb7-ad5f-2747a1ed7aab][/items/add][hello.login.web.item.ItemController#addItem(ItemSaveForm, BindingResult, RedirectAttributes)]
hello.login.web.item.ItemController#addItem(ItemSaveForm, BindingResult, RedirectAttributes)
가 실행된다.
h.l.w.interceptor.LoginCheckInterceptor : 인증 체크 인터셉터 실행 /items/add
postHandle
: 컨트롤러 호출 후에 호출된다.
hello.login.web.item.ItemController : errors=org.springframework.validation.BeanPropertyBindingResult: 2 errors
Field error in object 'item' on field 'quantity': rejected value [111111]; codes [Max.item.quantity,Max.quantity,Max.java.lang.Integer,Max]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [item.quantity,quantity]; arguments []; default message [quantity],9999]; default message [9999 이하여야 합니다]
Field error in object 'item' on field 'price': rejected value [12]; codes [Range.item.price,Range.price,Range.java.lang.Integer,Range]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [item.price,price]; arguments []; default message [price],1000000,1000]; default message [1000에서 1000000 사이여야 합니다]
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="items/addForm"; model={item=ItemSaveForm(itemName=itemA, price=12, quantity=111111), org.springframework.validation.BindingResult.item=org.springframework.validation.BeanPropertyBindingResult: 2 errors
Field error in object 'item' on field 'quantity': rejected value [111111]; codes [Max.item.quantity,Max.quantity,Max.java.lang.Integer,Max]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [item.quantity,quantity]; arguments []; default message [quantity],9999]; default message [9999 이하여야 합니다]
Field error in object 'item' on field 'price': rejected value [12]; codes [Range.item.price,Range.price,Range.java.lang.Integer,Range]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [item.price,price]; arguments []; default message [price],1000000,1000]; default message [1000에서 1000000 사이여야 합니다]}]]
9999 이하여야 합니다
, 1000에서 1000000 사이여야 합니다
: 오류 메세지를 넣은 적도 없는 데 이와 같이 출력된다. hibernate-validator
가 기본으로 제공하는 오류 메세지이다.@Range
, @Max
범위를 벗어난 값을 입력하였기에 발생하였다.
afterCompletion
: 뷰가 렌더링 된 이후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [74a14543-e8fb-4bb7-ad5f-2747a1ed7aab][/items/add][hello.login.web.item.ItemController#addItem(ItemSaveForm, BindingResult, RedirectAttributes)]
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [d705733c-31e8-4c2e-9006-72c247f7e8ff][/items/add][hello.login.web.item.ItemController#addItem(ItemSaveForm, BindingResult, RedirectAttributes)]
h.l.w.interceptor.LoginCheckInterceptor : 인증 체크 인터셉터 실행 /items/add
hello.login.web.item.ItemController : errors=org.springframework.validation.BeanPropertyBindingResult: 1 errors
Error in object 'item': codes [totalPriceMin.item,totalPriceMin]; arguments [10000,1000]; default message [null]
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="items/addForm"; model={item=ItemSaveForm(itemName=123, price=1000, quantity=1), org.springframework.validation.BindingResult.item=org.springframework.validation.BeanPropertyBindingResult: 1 errors
Error in object 'item': codes [totalPriceMin.item,totalPriceMin]; arguments [10000,1000]; default message [null]}]]
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [d705733c-31e8-4c2e-9006-72c247f7e8ff][/items/add][hello.login.web.item.ItemController#addItem(ItemSaveForm, BindingResult, RedirectAttributes)]
preHandle
: 컨트롤러 호출 전
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [d705733c-31e8-4c2e-9006-72c247f7e8ff][/items/add][hello.login.web.item.ItemController#addItem(ItemSaveForm, BindingResult, RedirectAttributes)]
hello.login.web.item.ItemController#addItem(ItemSaveForm, BindingResult, RedirectAttributes)
가 실행된다.
h.l.w.interceptor.LoginCheckInterceptor : 인증 체크 인터셉터 실행 /items/add
postHandle
: 컨트롤러 호출 후에 호출된다.
hello.login.web.item.ItemController : errors=org.springframework.validation.BeanPropertyBindingResult: 1 errors
Error in object 'item': codes [totalPriceMin.item,totalPriceMin]; arguments [10000,1000]; default message [null]
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="items/addForm"; model={item=ItemSaveForm(itemName=123, price=1000, quantity=1), org.springframework.validation.BindingResult.item=org.springframework.validation.BeanPropertyBindingResult: 1 errors
Error in object 'item': codes [totalPriceMin.item,totalPriceMin]; arguments [10000,1000]; default message [null]}]]
price
은 1000, quantity
은 1을 주었다.totalPriceMin
최소 값이 10,000
인데 현재 결과 1,000 * 1
로 작은 값이 입력되어 발생한 오류이다.
✔️ 메세지, 오류 설정
application.properties
spring.messages.basename=messages,errors
를 지정해야 한다.
이렇게 할시 messages.properties
, errors.properties
두 파일을 모두 인식한다.
생략할 시 messages.properties
를 기본으로 인식한다.
messages.properties
hello=안녕
hello.name=안녕 {0}
label.item=상품
label.item.id=상품 ID
label.item.itemName=상품명
label.item.price=가격
label.item.quantity=수량
page.items=상품 목록
page.item=상품 상세
page.addItem=상품 등록
page.updateItem=상품 수정
button.save=저장
button.cancel=취소
messages_en.properties
hello=hello
hello.name=hello {0}
label.item=Item
label.item.id=Item ID
label.item.itemName=Item Name
label.item.price=price
label.item.quantity=quantity
page.items=Item List
page.item=Item Detail
page.addItem=Item Add
page.updateItem=Item Update
button.save=Save
button.cancel=Cancel
errors.properties
#required.item.itemName=상품 이름은 필수입니다.
#range.item.price=가격은 {0} ~ {1} 까지 허용합니다.
#max.item.quantity=수량은 최대 {0} 까지 허용합니다.
#totalPriceMin=가격 * 수량의 합은 {0}원 이상이어야 합니다. 현재 값 = {1}
#==ObjectError==
#Level1
totalPriceMin.item=상품의 가격 * 수량의 합은 {0}원 이상이어야 합니다. 현재 값 = {1}
#Level2 - 생략
totalPriceMin=전체 가격은 {0}원 이상이어야 합니다. 현재 값 = {1}
#==FieldError==
#Level1
required.item.itemName=상품 이름은 필수입니다.
range.item.price=가격은 {0} ~ {1} 까지 허용합니다.
max.item.quantity=수량은 최대 {0} 까지 허용합니다.
#Level2 - 생략
#Level3
required.java.lang.String = 필수 문자입니다.
required.java.lang.Integer = 필수 숫자입니다.
min.java.lang.String = {0} 이상의 문자를 입력해주세요.
min.java.lang.Integer = {0} 이상의 숫자를 입력해주세요.
range.java.lang.String = {0} ~ {1} 까지의 문자를 입력해주세요.
range.java.lang.Integer = {0} ~ {1} 까지의 숫자를 입력해주세요.
max.java.lang.String = {0} 까지의 숫자를 허용합니다.
max.java.lang.Integer = {0} 까지의 숫자를 허용합니다.
#Level4
required = 필수 값 입니다.
min= {0} 이상이어야 합니다.
range= {0} ~ {1} 범위를 허용합니다.
max= {0} 까지 허용합니다.
typeMismatch.java.lang.Integer=숫자를 입력해주세요.
typeMismatch=타입 오류입니다.
#Bean Validation 추가
NotBlank={0} 공백X
Range={0}, {2} ~ {1} 허용
Max={0}, 최대 {1}
errors.properties
#Level1
totalPriceMin.item=상품의 가격 * 수량의 합은 {0}원 이상이어야 합니다. 현재 값 = {1}
가 현재 실행된다.
afterCompletion
: 뷰가 렌더링 된 이후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [d705733c-31e8-4c2e-9006-72c247f7e8ff][/items/add][hello.login.web.item.ItemController#addItem(ItemSaveForm, BindingResult, RedirectAttributes)]
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [d5284dee-e16c-49c6-896b-1ce7484f6463][/items/add][hello.login.web.item.ItemController#addItem(ItemSaveForm, BindingResult, RedirectAttributes)]
h.l.w.interceptor.LoginCheckInterceptor : 인증 체크 인터셉터 실행 /items/add
hello.login.domain.item.ItemRepository : Item id=3
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="redirect:/items/{itemId}"; model={itemId=3, status=true}]]
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [d5284dee-e16c-49c6-896b-1ce7484f6463][/items/add][hello.login.web.item.ItemController#addItem(ItemSaveForm, BindingResult, RedirectAttributes)]
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [9b49a512-566a-4644-a422-d3934a66f7b6][/items/3][hello.login.web.item.ItemController#item(long, Model)]
h.l.w.interceptor.LoginCheckInterceptor : 인증 체크 인터셉터 실행 /items/3
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="items/item"; model={item=Item(id=3, itemName=itemA, price=1000, quantity=10), org.springframework.validation.BindingResult.item=org.springframework.validation.BeanPropertyBindingResult: 0 errors}]]
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [9b49a512-566a-4644-a422-d3934a66f7b6][/items/3][hello.login.web.item.ItemController#item(long, Model)]
preHandle
: 컨트롤러 호출 전
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [d5284dee-e16c-49c6-896b-1ce7484f6463][/items/add][hello.login.web.item.ItemController#addItem(ItemSaveForm, BindingResult, RedirectAttributes)]
hello.login.web.item.ItemController#addItem(ItemSaveForm, BindingResult, RedirectAttributes)
가 실행된다.
h.l.w.interceptor.LoginCheckInterceptor : 인증 체크 인터셉터 실행 /items/add
postHandle
: 컨트롤러 호출 후에 호출된다.
hello.login.domain.item.ItemRepository : Item id=3
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="redirect:/items/{itemId}"; model={itemId=3, status=true}]]
afterCompletion
: 뷰가 렌더링 된 이후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [d5284dee-e16c-49c6-896b-1ce7484f6463][/items/add][hello.login.web.item.ItemController#addItem(ItemSaveForm, BindingResult, RedirectAttributes)]
preHandle
: 컨트롤러 호출 전
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [9b49a512-566a-4644-a422-d3934a66f7b6][/items/3][hello.login.web.item.ItemController#item(long, Model)]
hello.login.web.item.ItemController#item(long, Model)
이 실행된다.
templates/items/item
h.l.w.interceptor.LoginCheckInterceptor : 인증 체크 인터셉터 실행 /items/3
postHandle
: 컨트롤러 호출 후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="items/item"; model={item=Item(id=3, itemName=itemA, price=1000, quantity=10), org.springframework.validation.BindingResult.item=org.springframework.validation.BeanPropertyBindingResult: 0 errors}]]
afterCompletion
: 뷰가 렌더링 된 이후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [9b49a512-566a-4644-a422-d3934a66f7b6][/items/3][hello.login.web.item.ItemController#item(long, Model)]
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [678ecca3-ddf9-4a3d-8b27-eb01ca2d7401][/items][hello.login.web.item.ItemController#items(Model)]
h.l.w.interceptor.LoginCheckInterceptor : 인증 체크 인터셉터 실행 /items
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="items/items"; model={items=[Item(id=1, itemName=itemA, price=10000, quantity=10), Item(id=2, itemName=itemB, price=20000, quantity=20), Item(id=3, itemName=itemA, price=1000, quantity=10)]}]]
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [678ecca3-ddf9-4a3d-8b27-eb01ca2d7401][/items][hello.login.web.item.ItemController#items(Model)]
preHandle
: 컨트롤러 호출 전
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [678ecca3-ddf9-4a3d-8b27-eb01ca2d7401][/items][hello.login.web.item.ItemController#items(Model)]
hello.login.web.item.ItemController#items(Model)
을 실행된다.
itemRepository
에 있는 모든 아이템들을 model
에 추가한다.
templates/items/items
h.l.w.interceptor.LoginCheckInterceptor : 인증 체크 인터셉터 실행 /items
입력한 내용들을 검증한다. (추가 알게 되면 수정하기)
postHandle
: 컨트롤러 호출 후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="items/items"; model={items=[Item(id=1, itemName=itemA, price=10000, quantity=10), Item(id=2, itemName=itemB, price=20000, quantity=20), Item(id=3, itemName=itemA, price=1000, quantity=10)]}]]
items/items
에 아이템 3개를 띄워준다. (하나가 추가 됨)
afterCompletion
: 뷰가 렌더링 된 이후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [678ecca3-ddf9-4a3d-8b27-eb01ca2d7401][/items][hello.login.web.item.ItemController#items(Model)]
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [78a5a29b-416f-48d5-af25-7575db3faab3][/items/2][hello.login.web.item.ItemController#item(long, Model)]
h.l.w.interceptor.LoginCheckInterceptor : 인증 체크 인터셉터 실행 /items/2
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="items/item"; model={item=Item(id=2, itemName=itemB, price=20000, quantity=20), org.springframework.validation.BindingResult.item=org.springframework.validation.BeanPropertyBindingResult: 0 errors}]]
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [78a5a29b-416f-48d5-af25-7575db3faab3][/items/2][hello.login.web.item.ItemController#item(long, Model)]
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [abcdf814-0bf4-4a34-8c8c-d277bbf1e8e5][/items/2/edit][hello.login.web.item.ItemController#editForm(Long, Model)]
h.l.w.interceptor.LoginCheckInterceptor : 인증 체크 인터셉터 실행 /items/2/edit
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="items/editForm"; model={item=Item(id=2, itemName=itemB, price=20000, quantity=20), org.springframework.validation.BindingResult.item=org.springframework.validation.BeanPropertyBindingResult: 0 errors}]]
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [abcdf814-0bf4-4a34-8c8c-d277bbf1e8e5][/items/2/edit][hello.login.web.item.ItemController#editForm(Long, Model)]
preHandle
: 컨트롤러 호출 전
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [78a5a29b-416f-48d5-af25-7575db3faab3][/items/2][hello.login.web.item.ItemController#item(long, Model)]
hello.login.web.item.ItemController#item(long, Model)
이 실행된다.
templates/items/item
h.l.w.interceptor.LoginCheckInterceptor : 인증 체크 인터셉터 실행 /items/2
입력한 내용들을 검증한다. (추가 알게 되면 수정하기)
postHandle
: 컨트롤러 호출 후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="items/item"; model={item=Item(id=2, itemName=itemB, price=20000, quantity=20), org.springframework.validation.BindingResult.item=org.springframework.validation.BeanPropertyBindingResult: 0 errors}]]
items/item
에 선택된 item
이 띄워진다.
afterCompletion
: 뷰가 렌더링 된 이후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [78a5a29b-416f-48d5-af25-7575db3faab3][/items/2][hello.login.web.item.ItemController#item(long, Model)]
preHandle
: 컨트롤러 호출 전
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [abcdf814-0bf4-4a34-8c8c-d277bbf1e8e5][/items/2/edit][hello.login.web.item.ItemController#editForm(Long, Model)]
hello.login.web.item.ItemController#editForm(Long, Model)
이 실행된다.
itemId
를 찾아 model
에 추가한다.
templates/items/editForm
item
을 화면에 출력한다.
h.l.w.interceptor.LoginCheckInterceptor : 인증 체크 인터셉터 실행 /items/2/edit
입력한 내용들을 검증한다. (추가 알게 되면 수정하기)
postHandle
: 컨트롤러 호출 후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="items/editForm"; model={item=Item(id=2, itemName=itemB, price=20000, quantity=20), org.springframework.validation.BindingResult.item=org.springframework.validation.BeanPropertyBindingResult: 0 errors}]]
items
을 이제 보낸다.
afterCompletion
: 뷰가 렌더링 된 이후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [abcdf814-0bf4-4a34-8c8c-d277bbf1e8e5][/items/2/edit][hello.login.web.item.ItemController#editForm(Long, Model)]
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [1fde2503-4ac0-49b6-b762-469aa48216d1][/items/2/edit][hello.login.web.item.ItemController#edit(Long, ItemUpdateForm, BindingResult)]
h.l.w.interceptor.LoginCheckInterceptor : 인증 체크 인터셉터 실행 /items/2/edit
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="redirect:/items/{itemId}"; model={}]]
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [1fde2503-4ac0-49b6-b762-469aa48216d1][/items/2/edit][hello.login.web.item.ItemController#edit(Long, ItemUpdateForm, BindingResult)]
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [e33e50eb-afc5-42ba-85a5-b6c21be4f826][/items/2][hello.login.web.item.ItemController#item(long, Model)]
h.l.w.interceptor.LoginCheckInterceptor : 인증 체크 인터셉터 실행 /items/2
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="items/item"; model={item=Item(id=2, itemName=itemC, price=5000, quantity=300), org.springframework.validation.BindingResult.item=org.springframework.validation.BeanPropertyBindingResult: 0 errors}]]
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [e33e50eb-afc5-42ba-85a5-b6c21be4f826][/items/2][hello.login.web.item.ItemController#item(long, Model)]
preHandle
: 컨트롤러 호출 전
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [1fde2503-4ac0-49b6-b762-469aa48216d1][/items/2/edit][hello.login.web.item.ItemController#edit(Long, ItemUpdateForm, BindingResult)]
hello.login.web.item.ItemController#edit(Long, ItemUpdateForm, BindingResult)
이 실행된다.
totalPriceMin
을 호출한다.items/itemId
로 이동한다. (http://localhost:8080/items/2
)
리다이렉션(리다이렉트) 이해
: 웹 브라우저는 3xx 응답 결과에 Location
헤더가 있으면, Location
위치로 자동으로 이동한다.
➡️ 현재 Location
: items/2
h.l.w.interceptor.LoginCheckInterceptor : 인증 체크 인터셉터 실행 /items/2/edit
입력한 내용들을 검증한다. (추가 알게 되면 수정하기)
postHandle
: 컨트롤러 호출 후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="redirect:/items/{itemId}"; model={}]]
afterCompletion
: 뷰가 렌더링 된 이후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [1fde2503-4ac0-49b6-b762-469aa48216d1][/items/2/edit][hello.login.web.item.ItemController#edit(Long, ItemUpdateForm, BindingResult)]
preHandle
: 컨트롤러 호출 전
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [e33e50eb-afc5-42ba-85a5-b6c21be4f826][/items/2][hello.login.web.item.ItemController#item(long, Model)]
hello.login.web.item.ItemController#item(long, Model)
이 실행된다.
templates/items/item
h.l.w.interceptor.LoginCheckInterceptor : 인증 체크 인터셉터 실행 /items/2
입력한 내용들을 검증한다. (추가 알게 되면 수정하기)
postHandle
: 컨트롤러 호출 후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="items/item"; model={item=Item(id=2, itemName=itemC, price=5000, quantity=300), org.springframework.validation.BindingResult.item=org.springframework.validation.BeanPropertyBindingResult: 0 errors}]]
items/{itemId}/edit
에서 수정한 item
이 적용된다.
afterCompletion
: 뷰가 렌더링 된 이후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [e33e50eb-afc5-42ba-85a5-b6c21be4f826][/items/2][hello.login.web.item.ItemController#item(long, Model)]
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [19914b48-363d-480a-bf0f-4d94d7f36c65][/items][hello.login.web.item.ItemController#items(Model)]
h.l.w.interceptor.LoginCheckInterceptor : 인증 체크 인터셉터 실행 /items
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="items/items"; model={items=[Item(id=1, itemName=itemA, price=10000, quantity=10), Item(id=2, itemName=itemC, price=5000, quantity=300), Item(id=3, itemName=itemA, price=1000, quantity=10)]}]]
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [19914b48-363d-480a-bf0f-4d94d7f36c65][/items][hello.login.web.item.ItemController#items(Model)]
preHandle
: 컨트롤러 호출 전
h.login.web.interceptor.LogInterceptor : LogInterceptor preHandle REQUEST [19914b48-363d-480a-bf0f-4d94d7f36c65][/items][hello.login.web.item.ItemController#items(Model)]
hello.login.web.item.ItemController#items(Model)
을 실행된다.
itemRepository
에 있는 모든 아이템들을 model
에 추가한다.
templates/items/items
h.l.w.interceptor.LoginCheckInterceptor : 인증 체크 인터셉터 실행 /items
입력한 내용들을 검증한다. (추가 알게 되면 수정하기)
postHandle
: 컨트롤러 호출 후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor postHandle [ModelAndView [view="items/items"; model={items=[Item(id=1, itemName=itemA, price=10000, quantity=10), Item(id=2, itemName=itemC, price=5000, quantity=300), Item(id=3, itemName=itemA, price=1000, quantity=10)]}]]
items/items
에 아이템 3개를 띄워준다. (하나가 수정 됨)
afterCompletion
: 뷰가 렌더링 된 이후에 호출된다.
h.login.web.interceptor.LogInterceptor : LogInterceptor afterCompletion RESPONSE [19914b48-363d-480a-bf0f-4d94d7f36c65][/items][hello.login.web.item.ItemController#items(Model)]