Filter


Filter λŠ” javax.servlet νŒ¨ν‚€μ§€μ— ν¬ν•¨λ˜λŠ” 클래슀둜, DispatcherServlet 에 μš”μ²­μ΄ μ „λ‹¬λ˜κΈ° μ „ / 후에 url νŒ¨ν„΄μ— λ§žλŠ” λͺ¨λ“  μš”μ²­μ— λŒ€ν•΄ λΆ€κ°€ μž‘μ—…μ„ μ²˜λ¦¬ν•  수 μžˆλŠ” κΈ°λŠ₯을 μ œκ³΅ν•œλ‹€.

즉, ApplicationContext κ°€ μ•„λ‹Œ ν†°μΊ£κ³Ό 같은 Servlet Container 에 μ˜ν•΄ κ΄€λ¦¬λ˜κΈ°μ— μŠ€ν”„λ§μ˜ λ²”μœ„ λ°–μ—μ„œ μ²˜λ¦¬λœλ‹€.

Filter 의 생λͺ…μ£ΌκΈ°


package javax.servlet;
 
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()

ν•„ν„° 객체λ₯Ό μ΄ˆκΈ°ν™”ν•˜κ³  μ„œλΉ„μŠ€μ— μΆ”κ°€ν•˜κΈ° μœ„ν•œ λ©”μ„œλ“œλ‹€. μ„œλΈ”λ¦Ώ μ»¨ν…Œμ΄λ„ˆκ°€ 졜초둜 init() λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜μ—¬ ν•„ν„° 객체λ₯Ό μ΄ˆκΈ°ν™”ν•˜λ©΄ 이후 μš”μ²­λ“€μ€ doFilter() λ₯Ό 톡해 μ²˜λ¦¬λœλ‹€.

doFilter()

url-pattern 에 λ§žλŠ” λͺ¨λ“  HTTP μš”μ²­μ΄ DispatcherServlet 으둜 μ „λ‹¬λ˜κΈ° 전에 Servlet Container 에 μ˜ν•΄ μ‹€ν–‰λ˜λŠ” λ©”μ„œλ“œλ‹€.

FilterChain 을 톡해 λ‹€μŒ λŒ€μƒμœΌλ‘œ μš”μ²­μ„ μ „λ‹¬ν•˜μ—¬ μ „ / ν›„ 처리λ₯Ό 진행할 수 μžˆλ‹€.

destroy()

ν•„ν„° 객체λ₯Ό μ œκ±°ν•˜κ³  μ‚¬μš©ν•˜λŠ” μžμ›μ„ λ°˜ν™˜ν•˜κΈ° μœ„ν•œ λ©”μ„œλ“œλ‹€. Servlet Container κ°€ 졜초둜 destroy() λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜μ—¬ ν•„ν„° 객체λ₯Ό μ’…λ£Œν•˜λ©΄ μ΄ν›„μ—λŠ” doFilter() 에 μ˜ν•΄ μ²˜λ¦¬λ˜μ§€ μ•ŠλŠ”λ‹€.

Interceptor


Intercepter λŠ” Spring MVC νŒ¨ν‚€μ§€μ— ν¬ν•¨λ˜λŠ” 클래슀둜, Handler λ₯Ό μ‹€ν–‰ν•˜κΈ° μ „ / ν›„ 그리고 View λ₯Ό λ Œλ”λ§ν•œ ν›„ λΆ€κ°€ μž‘μ—…μ„ μ²˜λ¦¬ν•  수 μžˆλŠ” κΈ°λŠ₯을 μ œκ³΅ν•œλ‹€. 즉, ApplicationContext λ‚΄μ—μ„œ λ™μž‘ν•œλ‹€.

DispatcherServlet 이 HandlerMapping 을 톡해 Handler λ₯Ό 찾으면 HandlerExecutionChain 을 λ°˜ν™˜ν•œλ‹€. μ΄λ•Œ 1개 μ΄μƒμ˜ Interceptor κ°€ λ“±λ‘λ˜μ–΄ μžˆλ‹€λ©΄ 순차적으둜 Interceptor λ₯Ό 거쳐 Handler κ°€ μ‹€ν–‰λœλ‹€.

Interceptor λ©”μ„œλ“œ μ’…λ₯˜


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()

Handler κ°€ 호좜되기 전에 μ‹€ν–‰λ˜λ©° Handler 이전에 μ²˜λ¦¬ν•΄μ•Ό ν•˜λŠ” μ „μ²˜λ¦¬ μž‘μ—…μ΄λ‚˜ μš”μ²­ 정보λ₯Ό 가곡 λ˜λŠ” μΆ”κ°€ν•˜λŠ” κ²½μš°μ— μ‚¬μš©λœλ‹€.

postHandle()

Handler κ°€ 호좜된 후에 μ‹€ν–‰λ˜λ©° Handler 이후 μ²˜λ¦¬ν•΄μ•Ό ν•˜λŠ” ν›„μ²˜λ¦¬ μž‘μ—…μ΄ μžˆμ„ λ•Œ μ‚¬μš©ν•  수 μžˆλ‹€.

μ΅œκ·Όμ—λŠ” @RestController κ°€ 주둜 μ‚¬μš©λ˜μ–΄ 자주 μ‚¬μš©λ˜μ§€ μ•ŠλŠ”λ‹€.

afterCompletion()

λͺ¨λ“  View μ—μ„œ μ΅œμ’… κ²°κ³Όλ₯Ό μƒμ„±ν•˜λŠ” 일을 포함해 λͺ¨λ“  μž‘μ—…μ΄ μ™„λ£Œλœ 후에 μ‹€ν–‰λ˜λ©° μš”μ²­ 처리 쀑에 μ‚¬μš©ν•œ λ¦¬μ†ŒμŠ€λ₯Ό λ°˜ν™˜ν•  λ•Œ μ‚¬μš©ν•  수 μž‡λ‹€.

Filter 와 Interceptor 의 차이


  • Filter λŠ” 체이닝을 톡해 Request 와 Response λ₯Ό μ‘°μž‘ν•  수 μžˆμ§€λ§Œ, Interceptor λŠ” μ‘°μž‘ν•  수 μ—†λ‹€.
  • Filter λŠ” DispatcherServlet 외뢀에 μ‘΄μž¬ν•˜κΈ° λ•Œλ¬Έμ— ErrorController 둜 μ²˜λ¦¬ν•΄μ€˜μ•Ό ν•˜λŠ” 반면, Interceptor λŠ” @ControllerAdvice λ₯Ό 톡해 μ˜ˆμ™Έλ₯Ό μ²˜λ¦¬ν•  수 μžˆλ‹€.

Filter μ‚¬μš© μ˜ˆμ‹œ

  • λ³΄μ•ˆ 및 인증/인가 κ΄€λ ¨ μž‘μ—…
  • λͺ¨λ“  μš”μ²­μ— λŒ€ν•œ λ‘œκΉ… λ˜λŠ” 검사
  • 이미지/데이터 μ••μΆ• 및 λ¬Έμžμ—΄ 인코딩
  • Spring κ³Ό λΆ„λ¦¬λ˜μ–΄μ•Ό ν•˜λŠ” κΈ°λŠ₯

Interceptor μ‚¬μš© μ˜ˆμ‹œ

  • 세뢀적인 λ³΄μ•ˆ 및 인증/인가 곡톡 μž‘μ—…
  • API ν˜ΈμΆœμ— λŒ€ν•œ λ‘œκΉ… λ˜λŠ” 검사
  • Controller 둜 λ„˜κ²¨μ£ΌλŠ” 데이터 가곡

References