Intro
์ค๋์ Filter์ Interceptor์ ์ด์ผ๊ธฐ์ ๋๋ค. Spring์ ์ค์ํ ์์ ์ค ํ๋์ ๋๋ค. ํ์ง๋ง ์ ๋ฌด ํน์ฑ ๋๋ฌธ์ธ์ง ๊ฐ์ธ์ ์ผ๋ก๋ ์์ฃผ ์ ํ์ง ๋ชปํด ๋งค๋ฒ ๊น๋จน๋ ๋ถ๋ถ์ด๊ธฐ๋ ํฉ๋๋ค.
...์๊ฐํด๋ณด๋ฉด ์ ํ๋ ๊ฒ ์์ ๊ผฝ์ ๋งํผ ๋ณด์ง ๋ชปํ ๊ฑฐ ๊ฐ๋ค์.
Filter & Interceptor
Filter์ Interceptor๋ฅผ ์ฌ์ฉํ๋ ์ด์ ์๋ ์ค๋ณต ์ฝ๋ ๋ฌธ์ ๊ฐ ์์ต๋๋ค.
์น ๊ฐ๋ฐ์ ํ๋ค๋ณด๋ฉด ๊ณตํต ์ ๋ฌด(ํน์ ๊ณตํต ๊ด์ฌ์ฌ)์ ๊ด๋ จ๋ ๊ฒ๋ค์ด ์๊น๋๋ค. ์ด๋ฅผํ ๋ฉด ๋ก๊ทธ์ธ ๊ด๋ จ ์ฒ๋ฆฌ๋ ๊ถํ ํ์ธ๊ณผ ๊ฐ์ ๋ถ๋ถ์ด์ฃ . ์ด๋ฐ ๊ณตํต ์ ๋ฌด๋ ๋ค์์ ํ์ด์ง(ํน์ ์์ฒญ)์ ๋๊ฐ์ ์ฝ๋๊ฐ ํ์ํ๊ฒ ๋ฉ๋๋ค. ๊ฒฐ๊ตญ ์ค๋ณต ์ฝ๋๊ฐ ์๊ธฐ๋๊ฑฐ์ฃ .
์ด๋ฐ ๊ณตํต ์ ๋ฌด๋ค์ ์ฒ๋ฆฌํ ์ ์๋ ๊ธฐ๋ฅ์ด ๋ฐ๋ก Filter์ Interceptor์ ๋๋ค.
**AOP๋ ์์ต๋๋ค. ์ด๊ฑด ๋ค์ ๊ธ์์
Filter
Filter, ์ ํํ๊ฒ๋ Servlet Filter๋ Servlet ์ปจํ ์ด๋์ Servlet ์ฌ์ด๋ฅผ ์ค๊ฐ๋ ์์ฒญ๊ณผ ์๋ต์ ์ถ๊ฐ๋ก ๋ถ๊ฐ ์์ ์ ์งํํ ์ ์๋ ๊ธฐ๋ฅ์ ๋๋ค. ์ด๋ฌํ ๊ณผ์ ์ ๊ทธ๋ฆผ์ผ๋ก ํํํ๋ค๋ฉด ์๋์ ๊ฐ์ต๋๋ค.
์กฐ๊ธ ์ค๋๋ ๋ฌธ์์ง๋ง ์ฐธ๊ณ ์ฉ์ผ๋ก ์ ํฉํ ๊ฑฐ ๊ฐ์์ ๊ฐ์ ธ์๋ดค์ต๋๋ค. (Oracle์ด๋๊น ๊ด์ฐฎ์!)
๋ํ Filter๋ J2EE(Java 2 Enterprise Edition)์ ํ์ค ์คํ ๊ธฐ๋ฅ์ ๋๋ค.(์์์ ์ฐธ๊ณ ํ ๋ฌธ์์ ํ์ดํ๋ ‘Oracle9iAS Containers for J2EE Servlet Developer’s Guide’์ ๋๋ค.)
์ฆ, Filter๋ Spring๋ง์ ๊ธฐ๋ฅ์ด ์๋ Web ์ปจํ ์ด๋(ํน์ Servlet ์ปจํ ์ด๋)์์๋ ๋์ ๊ฐ๋ฅํ ๊ธฐ๋ฅ์ด๋ผ๋ ์ ์ด์ฃ . ๊ทธ๋ฆฌ๊ณ ์ด ๋ถ๋ถ์ด Interceptor์ Filter๋ฅผ ์ฌ์ฉํ๋๋ฐ ์ค์ํ ๊ตฌ๋ถ์ ์ด ๋ฉ๋๋ค.
Filter ๊ตฌํ
Filter๋ฅผ ๊ตฌํํ๊ธฐ ์ํด์๋ javax.servlet์ Filter ์ธํฐํ์ด์ค๋ฅผ implements ํด์ผ ํฉ๋๋ค.(org.springframework.boot:spring-boot-starter-web ์์กด์ฑ ์ถ๊ฐํ์๋ฉด ์์ต๋๋ค.)
Filter ์ธํฐํ์ด์ค๋ ์๋์ 3๊ฐ์ง ๋ฉ์๋๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค.
package javax.servlet;
import java.io.IOException;
public interface Filter {
public default void init(FilterConfig filterConfig) throws ServletException {}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException;
public default void destroy() {}
}
โฝinit
Filter๋ฅผ ์๋น์ค์ ์ถ๊ฐํ๊ธฐ ์ํด ๋ง๋ค์ด์ง ๋ฉ์๋์ ๋๋ค. init ๋ฉ์๋๋ web ์ปจํ ์ด๋์ ์ํด ์ ํํ ํ ๋ฒ ํธ์ถ๋ฉ๋๋ค.
โฝdoFilter
FilterChain์ ํตํด ์์ฒญ/์๋ต์ด ์ ๋ฌ๋ ๋๋ง๋ค ์ปจํ ์ด๋์์ ์์ฐจ์ ์ผ๋ก ํธ์ถ๋ฉ๋๋ค. ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌ๋ FilterChain์ ์ฌ์ฉํ์ฌ ํ๋ก์ธ์ค ์งํ ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํ ์ ์์ต๋๋ค.
โฝdestroy
Filter์ ์๋น์ค๊ฐ ์ค๋จ๋๊ณ ์์์ ๋ํ๋ด๊ธฐ ์ํ ๋ฉ์๋์ ๋๋ค. web ์ปจํ ์ด๋์ ์ํด ํธ์ถ๋๊ณ ๊ทธ ํ์๋ ํด๋น Filter ์ธ์คํด์ค์ doFilter ๋ฉ์๋๊ฐ ๋์ํ์ง ์์ต๋๋ค.
Interceptor
Interceptor๋ ์์ฒญ๊ณผ ์๋ต์ ๋ํด์ ์ถ๊ฐ๋ก ๋ถ๊ฐ ์์ ์ ์ํํฉ๋๋ค. Filter์ ๊ฐ์ ๊ธฐ๋ฅ์ ํ์ฃ . ํ์ง๋ง Filter์ ๋ฌ๋ฆฌ Interceptor๋ Spring์์ ์ ๊ณตํ๋ ๊ธฐ๋ฅ์ ๋๋ค. Filter์ ๊ฒฝ์ฐ์๋ javax.servlet ํจํค์ง ์๋์ ์์นํ๊ณ ์๋ค๋ฉด, Interceptor๋ org.springframework.web.servlet ์๋์ ์์นํ๊ณ ์์ฃ .
๋๋ฌธ์ ๋์ ์คํ ์์น๋ ์ฐจ์ด๊ฐ ๋ฉ๋๋ค. ๊ทธ๊ฑธ ๊ทธ๋ฆผ์ผ๋ก ํํํ๋ฉด ์๋์ ๊ฐ์ต๋๋ค.
Interceptor ๊ตฌํ
Filter๋ฅผ ๊ตฌํํ๊ธฐ ์ํด์ Filter ์ธํฐํ์ด์ค๋ฅผ ์ด์ฉํด์ผ ํ๋ค๋ฉด Interceptor์ ๊ฒฝ์ฐ์๋ HandlerInterceptor๋ฅผ implements ํ๋ฉด ๋ฉ๋๋ค. HandlerInterceptor๋ 3๊ฐ์ ๋ฉ์๋๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค.
package org.springframework.web.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.lang.Nullable;
import org.springframework.web.method.HandlerMethod;
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 {
}
}
โฝpreHandle
HandlerMapping์ด ์ ์ ํ ํธ๋ค๋ฌ(ํน์ ์ปจํธ๋กค๋ฌ) ๊ฐ์ฒด๋ฅผ ๊ฒฐ์ ํ ํ ๊ทธ๋ฆฌ๊ณ ์์ง HandlerAdapter๊ฐ ํธ๋ค๋ฌ๋ฅผ ํธ์ถํ๊ธฐ ์ ์ ์คํ๋ฉ๋๋ค. ๋๋ฌธ์ ์ธ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ์ธ Handler์๋ HandlerMapping์ด ๊ฒฐ์ ํ ์ปจํธ๋กค๋ฌ๊ฐ ๋งคํ๋ HandlerMethod๊ฐ ๋ด๊ฒจ์์ต๋๋ค.
๋ํ preHandle์ return type์ Booolean์ ๋๋ค. true๊ฐ ๋ฆฌํด๋๋ ๊ฒฝ์ฐ์๋ ๋ค์ ๋จ๊ณ๋ก ์งํ์ด ๋์ง๋ง, false๋ผ๋ฉด ์ดํ์ ์์ ์ด ์งํ๋์ง ์์ต๋๋ค.
โฝpostHandle
HandlerAdapter๊ฐ ์ค์ ๋ก ํธ๋ค๋ฌ๋ฅผ ํธ์ถํ ํ(ํน์ Dispatcher Servlet์ด ๋ทฐ๋ฅผ ๋๋๋งํ๊ธฐ ์ )์ ํธ์ถ๋ฉ๋๋ค.
๋ํ ํ๋ผ๋ฏธํฐ๋ก ์ฃผ์ด์ง๋ ModelAndView๋ฅผ ํตํด ๋ทฐ์ ์ ๋ณด๋ฅผ ์ถ๊ฐํ ์ ์์ต๋๋ค.
โฝafterCompletion
์์ฒญ ์ฒ๋ฆฌ ์๋ฃ ํ, ์ฆ ๋ทฐ๋ฅผ ๋๋๋งํ ํ ์คํ๋ฉ๋๋ค.
ํน์ดํ ์ ์ ํธ๋ค๋ฌ ์คํ ์ค์ ์๋ฌ๊ฐ ๋ฐ์๋์ด๋ afterCompletion์ ํธ์ถ๋ฉ๋๋ค.(postHandle์ ํธ์ถ๋์ง ์์ต๋๋ค.)
Filter vs Interceptor
Filter์ Interceptor๋ ๊ฒฐ๊ตญ ์์ฒญ๊ณผ ์๋ต์ ๋ํด์ ์ถ๊ฐ๋ก ๋ถ๊ฐ ์์ ์ ์งํํ๋ค๋ผ๋ ์ธก๋ฉด์์ ๋๊ฐ์ต๋๋ค. ๋ฌผ๋ก ์ธ๋ถ์ ์ผ๋ก ์กฐ๊ธ ๋ค๋ฆ ๋๋ค.
Filter๋ doFilter ํ๋๋ง ์ ๊ณต๋๊ณ , Interceptor์์๋ ์งํ ๋จ๊ณ์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ์ฌ์ฉํ ์ ์๊ฒ pre, post, after๋ก ์ธ๋ถํ๋ ๊ฒ์ฒ๋ผ ๋ง์ด์ฃ .
ํ์ง๋ง Filter์ Interceptor์ ์ฐจ์ด์ ์ ์กฐ๊ธ ๋ ๋ช ํํ๊ฒ ๋๋ผ๋ ค๋ฉด ๋์ ์คํ ์์น๋ฅผ ๋์ฌ๊ฒจ๋ด์ผ ํฉ๋๋ค.
โฝFilter
๋ web ์ปจํ ์ด๋ ์์ญ์์ Dispatcher Servlet ์์์ ๋์ํฉ๋๋ค.
์๋ฅผ ๋ค๋ฉด ๋ณด์์ด๋ ๋ก๊ทธ์ธ ๊ด๋ จ ๊ณตํต ์ ๋ฌด๋ Filter๊ฐ Interceptor๋ณด๋ค ๋ ์ ์ฉํฉ๋๋ค. ์๋ํ๋ฉด ์ธ์ฆ๋์ง ์์ ์ฌ์ฉ์๋ฅผ ํ ๋จ๊ณ๋ผ๋ ๋ฐ(์)์์ ๊ฑธ๋ฌ๋ผ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
๋ํ Filter๋ Servlet(Dispatcher Servlet)์ ๋์ฐฉํ๊ธฐ ์ ์ ๋์ํ๊ธฐ ๋๋ฌธ์ Servlet ๋ฐ๊ฟ์น๊ธฐ๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
โฝInterceptor
๋ Spring ์์ญ์์ Dispatcher Servlet ๋ค์์ ๋์ํฉ๋๋ค.
์์ ์๊ธฐํ๋ ๋ก๊ทธ์ธ ๊ด๋ จ ๊ณตํต ์ ๋ฌด์ ๋น์ทํ์ง๋ง ์กฐ๊ธ ๋ค๋ฅธ ๊ถํ ๊ด๋ จ ์ ๋ฌด๋ Filter๋ณด๋จ Interceptor๊ฐ ๋ ์ ์ฉํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค๋ฉด ๊ถํ์ ๋ฐ๋ผ ํ๋ฉด์ ๋ ธ์ถ๋๋ ํญ๋ชฉ์ ๋ค๋ฅด๊ฒ ํ๊ธฐ์๋ Interceptor์ postHandle์ด ์ ํฉํ์ฃ .
๋ํ ๊ฐ ๊ถํ์ ๋ฐ๋ฅธ ์๋ฌ ์ฒ๋ฆฌ๋ฅผ Spring ์์ญ์์ ํ ์ ์๊ธฐ ๋๋ฌธ์ ๊ด๋ฆฌ๊ฐ ์ฌ์์ง๋ ์ธก๋ฉด๋ ์์ต๋๋ค. ๊ถํ ๊ด๋ จ ์ ๋ฌด๋ฟ๋ง ์๋๋ผ ๋ง์ฝ ์์ธ ์ฒ๋ฆฌ๋ฅผ ์ ์ญ(๊ณตํต)์ผ๋ก ํ๊ณ ์ถ๋ค๋ฉด Interceptor๊ฐ ์ ์ฉํ๊ฒ ์ฃ .
Ending
Filter์ Interceptor. ์ฐจ์ด์ ์ด ์๊ธด ํ์ง๋ง ํฌ์ง ์์ต๋๋ค. ์๊ตฌ์ฌํญ์ ๋ฐ๋ผ์๋ ๋ฌด์์ ์จ๋ ๋ฌด๋ฐฉํ ๊ฒฝ์ฐ๋ ์์ ๊ฑฐ๋ผ ์๊ฐํฉ๋๋ค. ํ์ง๋ง ์ด๋ ๋์๋ ๋ ์ค ํ๋๊ฐ ์กฐ๊ธ ๋ ์ ์ฉํ ์ ์์ต๋๋ค. ๊ทธ๋ฐ ๋๊ฐ ์ค๋ฉด ์ ๊ฐ ์ด ๊ธ์ ์์ฑํ๋ฉฐ ์ป์๋ ๊ฒ๋ค์ด ์กฐ๊ธ์ด๋ผ๋ ๋์์ด ๋๊ธธ ๋ฐ๋๋๋ค.
(์ด ๊ธ์์ ํ์ฉํ๋ ์์ค ์ฝ๋๋ ์ด๊ณณ์์ ํ์ธ ๊ฐ๋ฅํ์ญ๋๋ค.)
๋๊ธ