์๋ธ๋ฆฟ ํํฐ์ ๊ฐ์ด ์คํ๋ง ์ธํฐ์ ํฐ(Spring Interceptor) ๋ํ ์น๊ณผ ๊ด๋ จ๋ ๊ณตํต ๊ด์ฌ ์ฌํญ์ ํจ๊ณผ์ ์ผ๋ก ํด๊ฒฐํ ์ ์๋ ๊ธฐ์ ์ด๋ค.
์ด๋ฒ ๊ธ์ ํตํด '์คํ๋ง ์ธํฐ์ ํฐ์ ๊ฐ๋ '์ ์์๋ณด๊ณ , '์์ฒญ ๋ก๊ทธ ์์ '์ '์ธ์ฆ ์ฒดํฌ ์์ '๋ฅผ ํตํด์ ์ฌ์ฉ ๋ฐฉ๋ฒ์ ์์๋ณด๋๋ก ํ์.
1. ๊ฐ๋ ๐
๐ 1. ์คํ๋ง ์ธํฐ์ ํฐ ํ๋ฆ
์คํ๋ง ์ธํฐ์ ํฐ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ค์๊ณผ ๊ฐ์ ํ๋ฆ์ ๊ฐ์ง๋ค.
HTTP ์์ฒญ → WAS → ํํฐ → ์๋ธ๋ฆฟ(Dispatcher Servlet) → ์คํ๋ง ์ธํฐ์ ํฐ → ์ปจํธ๋กค๋ฌ
์คํ๋ง ์ธํฐ์ ํฐ๋ ๋์คํจ์ฒ ์๋ธ๋ฆฟ๊ณผ ์ปจํธ๋กค๋ฌ ์ฌ์ด์์ ์ปจํธ๋กค๋ฌ ํธ์ถ ์ง์ ์ ํธ์ถ๋๋ค.
๐ 2. ์คํ๋ง ์ธํฐ์ ํฐ ์ ํ
์๋ธ๋ฆฟ ํํฐ์ ๊ฐ์ด ๋ก๊ทธ์ธํ์ง ์์ ์ฌ์ฉ์์ ์ ๊ทผ๊ณผ ๊ฐ์ '์ ์ ํ์ง ์์ ์์ฒญ'์ ๋ํ์ฌ ํ๋จํ๊ณ ๊ฑฐ๊ธฐ์์ ๋์ ๋ผ ์ ์๋ค.
(1) ๋ก๊ทธ์ธํ ์ฌ์ฉ์์ธ ๊ฒฝ์ฐ
HTTP ์์ฒญ → WAS → ํํฐ → ์๋ธ๋ฆฟ → ์คํ๋ง ์ธํฐ์ ํฐ → ์ปจํธ๋กค๋ฌ
(2) ๋ก๊ทธ์ธํ์ง ์์ ์ฌ์ฉ์์ธ ๊ฒฝ์ฐ
HTTP ์์ฒญ → WAS → ํํฐ → ์๋ธ๋ฆฟ → ์คํ๋ง ์ธํฐ์ ํฐ
๐ 3. ์คํ๋ง ์ธํฐ์ ํฐ ์ฒด์ธ
์คํ๋ง ์ธํฐ์ ํฐ๋ ์ฒด์ธ์ผ๋ก ๊ตฌ์ฑ๋๋ค
HTTP ์์ฒญ → WAS → ํํฐ → ์๋ธ๋ฆฟ → ์ธํฐ์ ํฐ1 → ์ธํฐ์ ํฐ2 → ์ปจํธ๋กค๋ฌ
๊ทธ๋์ ์ฌ๋ฌ ์ธํฐ์ ํฐ๋ฅผ ์ ์ฉํ ์ ์๋ค. ์๋ฅผ ๋ค์ด ๋ก๊ทธ๋ฅผ ๋จ๊ธฐ๋ ์ธํฐ์ ํฐ๋ฅผ ๋จผ์ ์ ์ฉํ๊ณ , ๊ทธ๋ฆฌ๊ณ ๋ก๊ทธ์ธ ์ฌ๋ถ๋ฅผ ์ฒดํฌํ๋ ์ธํฐ์ ํฐ๋ฅผ ์ ์ฉํ ์ ์๋ค.
๐ 4. ์คํ๋ง ์ธํฐ์ ํฐ ์ธํฐํ์ด์ค
public interface HandlerInterceptor {
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable ModelAndView modelAndView) throws Exception {
}
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable Exception ex) throws Exception {
}
}
์คํ๋ง ์ธํฐ์ ํฐ๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด HandlerInterceptor ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ฉด ๋๋ค.
์๋ธ๋ฆฟ ํํฐ์ ๊ฒฝ์ฐ doFilter()๋ก๋ง ๋ก์ง์ ์ฒ๋ฆฌํ ์ ์์๋๋ฐ, ์ธํฐ์ ํฐ๋ preHandle(์ปจํธ๋กค๋ฌ ํธ์ถ ์ ), postHandle(์ปจํธ๋กค๋ฌ ํธ์ถ ํ), afterCompletion(์์ฒญ ์๋ฃ ์ดํ)์ ๊ฐ์ด ์ฌ๋ฌ ๋จ๊ณ์์ ๋ก์ง์ ์ํํ ์ ์๋ค.
- preHandle
์ปจํธ๋กค๋ฌ ํธ์ถ ์ ์ ํธ์ถ๋๋ค. (์ ํํ๋ ํธ๋ค๋ฌ ์ด๋ํฐ๊ฐ ํธ์ถ๋๊ธฐ ์ ์ ํธ์ถ๋๋ค.)
preHandle์ ์๋ต๊ฐ์ด true์ด๋ฉด ๋ค์์ ์งํํ๊ณ , false์ด๋ฉด ์งํํ์ง ์๋๋ค. (false์ด๋ฉด 1๋ฒ ๊ณผ์ ์์ ๋์ด ๋๋ค.) - postHandle
์ปจํธ๋กค๋ฌ ํธ์ถ ํ์ ํธ์ถ๋๋ค. (์ ํํ๋ ํธ๋ค๋ฌ ์ด๋ํฐ ํธ์ถ ํ์ ํธ์ถ๋๋ค.) - afterCompletion
๋ทฐ๊ฐ ๋๋๋ง ๋ ์ดํ์ ํธ์ถ๋๋ค.
๋ํ, 'Object handler'๋ฅผ ์ด์ฉํ์ฌ ์ด๋ค ์ปจํธ๋กค๋ฌ๊ฐ ํธ์ถ๋๋์ง ํธ์ถ์ ๋ณด๋ฅผ ๋ฐ์ ์ ์๊ณ , 'ModelAndView modelAndView'๋ฅผ ์ด์ฉํ์ฌ ์ด๋ค ๋ด์ฉ๋ค์ด ๋ฐํ๋๋์ง ์๋ต ์ ๋ณด๋ ๋ฐ์ ์ ์๋ค.
๐ 5. ์์ธ๊ฐ ๋ฐ์ํ ์ํฉ์์์ ํ๋ฆ
์์ธ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ ์๋์ ๊ฐ์ด ์งํ๋๋ค.
- preHandle
์ปจํธ๋กค๋ฌ ํธ์ถ ์ ์ ํธ์ถ๋๋ค. - postHandle
์ปจํธ๋กค๋ฌ์์ ์์ธ๊ฐ ๋ฐ์ํ๋ฉด postHandle์ ํธ์ถ๋์ง ์๋๋ค. - afterCompletion
ํญ์ ํธ์ถ๋๋ค.
์์ธ๊ฐ ๋ฐ์ํ๋ฉด ์์ธ(ex)๋ฅผ ํ๋ผ๋ฏธํฐ๋ก ๋ฐ์์ ์ด๋ค ์์ธ๊ฐ ๋ฐ์ํ๋์ง ๋ก๊ทธ๋ก ์ถ๋ ฅํ ์ ์๋ค.
์์ธ์ ๋ฌด๊ดํ๊ฒ ๊ณตํต ์ฒ๋ฆฌ๋ฅผ ํ๋ ค๋ฉด postHandle์ด ์๋๋ผ afterCompletion์ ์ฌ์ฉํด์ผ ํ๋ค.
2. ์์ฒญ ๋ก๊ทธ ์์ ๐
@Slf4j
public class LogInterceptor implements HandlerInterceptor {
public static final String LOG_ID = "logId";
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
String requestURI = request.getRequestURI();
String uuid = UUID.randomUUID().toString(); // HTTP ์์ฒญ์ ๊ตฌ๋ถํ๊ธฐ ์ํ ๊ฒ
request.setAttribute(LOG_ID, uuid);
if(handler instanceof HandlerMethod){
HandlerMethod hm = (HandlerMethod) handler; // ํธ์ถํ ์ปจํธ๋กค๋ฌ ๋ฉ์๋์ ๋ชจ๋ ์ ๋ณด๊ฐ ๋ด๊ฒจ ์๋ค.
}
log.info("REQUEST [{}][{}][{}]", uuid, requestURI, handler);
return true; // false์ธ ๊ฒฝ์ฐ ๋ ์ด์ ์งํ๋์ง ์๋๋ค.
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
log.info("postHandle [{}]", modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
String requestURI = request.getRequestURI();
String logId = (String) request.getAttribute(LOG_ID);
log.info("RESPONSE [{}][{}]", logId, requestURI);
if(ex != null){
log.error("afterCompletion error!!", ex);
}
}
}
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LogInterceptor()) // ์ธํฐ์
ํฐ ๋ฑ๋ก
.order(1) // ํธ์ถ์์ ์ง์
.addPathPatterns("/**") // ์ธํฐ์
ํฐ๋ฅผ ์ ์ฉํ URL ํจํด ์ง์
.excludePathPatterns("/css/**", "/*.ico", "/error"); // ์ธํฐ์
ํฐ์์ ์ ์ธํ ํจํด ์ง์
}
}
WebMvcConfigurer๊ฐ ์ ๊ณตํ๋ addInterceptors()๋ฅผ ์ฌ์ฉํด์ ์ธํฐ์ ํฐ๋ฅผ ๋ฑ๋กํ ์ ์๋ค.
addInterceptor()๋ฅผ ์ด์ฉํด์ ์ธํฐ์ ํฐ๋ฅผ ๋ฑ๋กํ๊ณ , order()๋ฅผ ์ด์ฉํด์ ํธ์ถ ์์๋ฅผ ์ง์ ํ๊ณ , addPathPatterns()๋ฅผ ์ด์ฉํด์ ์ธํฐ์ ํฐ๋ฅผ ์ ์ฉํ URL ํจํด์ ์ง์ ํ๊ณ , excludePathPatterns()๋ฅผ ์ง์ ํด์ ์ธํฐ์ ํฐ์์ ์ ์ธํ ํจํด์ ์ง์ ํ๋ฉด ๋๋ค.
์คํ์์ผ ๋ณด๋ฉด ๋ก๊ทธ๋ ์๋์ ๊ฐ์ด ๋์ค๊ฒ ๋๋ค.
2023-04-30T00:18:11.301+09:00 INFO 22272 --- [nio-8080-exec-1] com.interceptor.LogInterceptor : REQUEST [18844889-7f8f-4b7f-8848-1b04472c65bb][/][com.interceptor.MainController#index(Model)]
2023-04-30T00:18:11.314+09:00 INFO 22272 --- [nio-8080-exec-1] com.interceptor.LogInterceptor : postHandle [ModelAndView [view="home"; model={}]]
2023-04-30T00:18:11.665+09:00 INFO 22272 --- [nio-8080-exec-1] com.interceptor.LogInterceptor : RESPONSE [18844889-7f8f-4b7f-8848-1b04472c65bb][/]
3. ์ธ์ฆ ์ฒดํฌ ์์ ๐
@Slf4j
public class LoginCheckInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
String requestURI = request.getRequestURI();
log.info("์ธ์ฆ ์ฒดํฌ ์ธํฐ์
ํฐ ์คํ {}", requestURI);
HttpSession session = request.getSession();
// ์ธ์ฆ์ด ๋์ง ์์ ๊ฒฝ์ฐ
if(...) {
log.info("๋ฏธ์ธ์ฆ ์ฌ์ฉ์ ์์ฒญ");
// ๋ก๊ทธ์ธ์ผ๋ก redirect
response.sendRedirect("/login?redirectURL="+requestURI);
return false;
}
return true;
}
}
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LogInterceptor())
...
registry.addInterceptor(new LoginCheckInterceptor()) // ์ธํฐ์
ํฐ ๋ฑ๋ก
.order(2) // ํธ์ถ์์ ์ง์
.addPathPatterns("/**") // ์ธํฐ์
ํฐ๋ฅผ ์ ์ฉํ URL ํจํด ์ง์
.excludePathPatterns("/", "/members/add", "/login", "/logout",
"/css/**", "/*.ico", "/error"); // ์ธํฐ์
ํฐ์์ ์ ์ธํ ํจํด ์ง์
}
}
'ํ, ํ์๊ฐ์ , ๋ก๊ทธ์ธ, ๋ฆฌ์์ค ์กฐํ, ์ค๋ฅ'์ ๊ฐ์ ๋ถ๋ถ์ ๋ก๊ทธ์ธ ์ฒดํฌ ์ธํฐ์ ํฐ๋ฅผ ์ ์ฉํ์ง ์๋๋ก ํ์๋ค.
๊ทธ๋ฆฌ๊ณ ๋ก๊ทธ์ธ์ ํ ์ดํ ๋ค์ ์๋ ํ์ด์ง๋ก ๋์์ค๊ฒ ํ๊ธฐ ์ํด์ redirectURL์ ํ๋ผ๋ฏธํฐ๋ก ๋ถ์ฌ์ฃผ์๋ค.
ํด๋น ๊ธ์ ๊น์ํ ๋์ '์คํ๋ง MVC 2ํธ - ๋ฐฑ์๋ ์น ๊ฐ๋ฐ ํ์ฉ ๊ธฐ์ '์ ์ฐธ๊ณ ํ์์ต๋๋ค.
'๐ ์คํ๋ง > ๊ธฐ๋ณธ ๊ฐ๋ ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Spring] ๊ฒ์ฆ(Validation) - bindingResult.rejectValue(), binding.reject() (0) | 2023.05.02 |
---|---|
[Spring] ๊ฒ์ฆ(Validation) - BindingResult, FieldError, ObjectError (0) | 2023.05.01 |
์๋ธ๋ฆฟ ํํฐ(Servlet Filter) (0) | 2023.04.29 |
๋ฉ์์ง & ๊ตญ์ ํ (Message & Internationalization) (0) | 2023.04.25 |
HTTP ์๋ต(์ ์ ๋ฆฌ์์ค, ๋ทฐ ํ ํ๋ฆฟ, HTTP ๋ฉ์์ง) ์ฒ๋ฆฌ (0) | 2023.04.21 |