๋ฐฑ์—”๋“œ(Back-End) ๊ฐœ๋ฐœ/Spring

[Spring] ํ•„ํ„ฐ(Filter) vs ์ธํ„ฐ์…‰ํ„ฐ(Interceptor)

rabo93 2025. 7. 7. 15:39
๊ฐœ๋ฐœ์„ ํ•˜๋‹ค๋ณด๋ฉด ๊ณตํ†ต์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์•ผํ•  ์—…๋ฌด๊ฐ€ ๋งŽ๋‹ค.

๊ณตํ†ต ์—…๋ฌด์—์„œ ์ค‘๋ณต ์ฝ”๋“œ๊ฐ€ ๋งŽ์•„์ง€๊ฑฐ๋‚˜ ํ”„๋กœ์ ํŠธ ๋‹จ์œ„๊ฐ€ ์ปค์งˆ์ˆ˜๋ก ์„œ๋ฒ„์— ๋ถ€ํ•˜๋ฅผ ์ฃผ๋ฉฐ, ์†Œ์Šค ๊ด€๋ฆฌ๋„ ๋˜์ง€ ์•Š๋Š”๋‹ค.

๋”ฐ๋ผ์„œ, Spring์—์„œ ์ค‘๋ณต ์ฝ”๋“œ๋ฅผ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.

ํ•„ํ„ฐ(Filter)์™€ ์ธํ„ฐ์…‰ํ„ฐ(Interceptor)๋Š” ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์š”์ฒญ/์‘๋‹ต ์ฒ˜๋ฆฌ ์ „/ํ›„์— ๊ณตํ†ต์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ๊ธฐ๋Šฅ

 

 

(Servlet)ํ•„ํ„ฐ => Java EE ํ‘œ์ค€ ์ŠคํŽ™ Dispatcher Servlet์—์„œ ์ œ๊ณต 

(Spring)์ธํ„ฐ์…‰ํ„ฐ => Spring MVC์—์„œ ์ œ๊ณต

HTTP ์š”์ฒญ WAS   "ํ•„ํ„ฐ"   ์„œ๋ธ”๋ฆฟ   ์ปจํŠธ๋กค๋Ÿฌ

HTTP ์š”์ฒญ  WAS   ํ•„ํ„ฐ   ์„œ๋ธ”๋ฆฟ →  "์ธํ„ฐ์…‰ํ„ฐ" ์ปจํŠธ๋กค๋Ÿฌ


1. Servlet Filter 

  • ๋””์ŠคํŒจ์ฒ˜ ์„œ๋ธ”๋ฆฟ ์š”์ฒญ์ด ์ „๋‹ฌ๋˜๊ธฐ ์ „/ํ›„์— ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๋ฏ€๋กœ ํ†ต์บฃ๊ณผ ๊ฐ™์€ ์›น ์ปจํ…Œ์ด๋„ˆ์— ์˜ํ•ด ๊ด€๋ฆฌ๋˜๊ณ , ์Šคํ”„๋ง ๋ฒ”์œ„ ๋ฐ–์—์„œ ์ฒ˜๋ฆฌ๋จ
  • jacax.servlet ์— ๋“ฑ๋ก๋œ Filter ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ๋“ฑ๋กํ•˜๋ฉด, ์„œ๋ธ”๋ฆฟ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ํ•„ํ„ฐ๋ฅผ ์‹ฑ๊ธ€ํ†ค ๊ฐ์ฒด๋กœ ์ƒ์„ฑํ•˜๊ณ  ๊ด€๋ฆฌํ•จ  javax.servlet.Filter์˜ 3๊ฐ€์ง€ ๋ฉ”์†Œ๋“œ
    1. init() - ์ฒ˜์Œ 1ํšŒ
    2. doFilter()
    3. destroy() - ๋ 1ํšŒ
public interface Filter {
	// init() ๋ฉ”์†Œ๋“œ (์ฒ˜์Œ)
    // - ํ•„ํ„ฐ ๊ฐ์ฒด๋ฅผ ์ดˆ๊ธฐํ™” ํ•˜๊ณ  ์„œ๋น„์Šค์— ์ถ”๊ฐ€
    // - ์›น ์ปจํ…Œ์ด๋„ˆ๊ฐ€ 1ํšŒ init ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœํ•˜์—ฌ ํ•„ํ„ฐ ๊ฐ์ฒด๋ฅผ ์ดˆ๊ธฐํ™” ํ•˜๋ฉด ์ดํ›„์˜ ์š”์ฒญ๋“ค์€ doFilter๋ฅผ ํ†ตํ•ด ์ฒ˜๋ฆฌ
    public default void init(FilterConfig filterConfig) throws ServletException {}
    
    // doFilter() ๋ฉ”์†Œ๋“œ
    // - url-pattern์— ๋งž๋Š” ๋ชจ๋“  HTTP ์š”์ฒญ์ด ๋””์ŠคํŒจ์ฒ˜ ์„œ๋ธ”๋ฆฟ์œผ๋กœ ์ „๋‹ฌ๋˜๊ธฐ ์ „์— ์›น ์ปจํ…Œ์ด๋„ˆ์— ์˜ํ•ด ์‹คํ–‰๋จ
    // - ํŒŒ๋ผ๋ฏธํ„ฐ : FilterChain => chain.doFilter() ์ „/ํ›„์— ์šฐ๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ ์ฒ˜๋ฆฌ ๊ณผ์ •์„ ๋„ฃ์–ด์คŒ
    public void doFilter(ServletRequest request, ServletResponse response,
            		FilterChain chain) throws IOException, ServletException{
        System.out.println("Filter ์‹คํ–‰ ์ „");
        chain.doFilter(request, response); // ๋‹ค์Œ ํ•„ํ„ฐ or ์„œ๋ธ”๋ฆฟ ํ˜ธ์ถœ
        System.out.println("Filter ์‹คํ–‰ ํ›„");
    }
	
    // destroy() ๋ฉ”์†Œ๋“œ (๋)
    // - ํ•„ํ„ฐ ๊ฐ์ฒด๋ฅผ ์„œ๋น„์Šค์—์„œ ์ œ๊ฑฐ
    // - ์›น ์ปจํ…Œ์ด๋„ˆ๊ฐ€ 1ํšŒ ํ˜ธ์ถœ๋˜๋ฉฐ, ์ดํ›„๋Š” doFilter์— ์˜ํ•ด ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์Œ
    public default void destroy() {}
}
  • ์šฉ๋„
    • ์ธ์ฝ”๋”ฉ ์„ค์ • (UTF-8)
    • ๊ณตํ†ต๋œ ์ธ์ฆ ์ฒ˜๋ฆฌ
    • ๋ชจ๋“  ์š”์ฒญ์— ๋Œ€ํ•œ ๋กœ๊น…/๋ชจ๋‹ˆํ„ฐ๋ง
    • CORS ์ฒ˜๋ฆฌ
    • ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฐ€๊ณต
    • Spring๊ณผ ๋ถ„๋ฆฌ๋˜์–ด์•ผํ•˜๋Š” ๊ธฐ

2. Spring Interceptor

  • ๋””์ŠคํŒจ์ฒ˜ ์„œ๋ธ”๋ฆฟ์ด ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ์ „/ํ›„ ์š”์ฒญ๊ณผ ์‘๋‹ต์„ ์ฐธ์กฐํ•˜๊ฑฐ๋‚˜ ๊ฐ€๊ณตํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ Spring Context์—์„œ ๋™์ž‘
  • org.springframework.web.servlet์˜ HandlerInterceptor ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„(3๊ฐ€์ง€ ๋ฉ”์†Œ๋“œ)
    1. preHandle() - ์ปจํŠธ๋กค๋Ÿฌ ํ˜ธ์ถœ ์ „
    2. postHandle() - ์ปจํŠธ๋กค๋Ÿฌ ํ˜ธ์ถœ ํ›„
    3. afterCompletion() - ๋ชจ๋“  ์ž‘์—…์ด ์™„๋ฃŒ๋œ ํ›„
public interface HandlerInterceptor {
    // preHandel() ๋ฉ”์†Œ๋“œ
    // - ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ํ˜ธ์ถœ๋˜๊ธฐ ์ „์— ์‹คํ–‰. ์ปจํŠธ๋กค๋Ÿฌ ์ด์ „์— ์ฒ˜๋ฆฌํ•ด์•ผํ•˜๋Š” ์ „์ฒ˜๋ฆฌ ์ž‘์—…์ด๋‚˜ ์š”์ฒญ์ •๋ณด๋ฅผ ๊ฐ€๊ณตํ•˜๊ฑฐ๋‚˜ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ์— ์‚ฌ์šฉ
    // - handler ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ํ•ธ๋“ค๋Ÿฌ ๋งคํ•‘์ด ์ฐพ์•„์ค€ ์ปจํŠธ๋กค๋Ÿฌ ๋นˆ์— ๋งคํ•‘๋˜๋Š” HandlerMethod๋ผ๋Š” ์ƒˆ๋กœ์šด ํƒ€์ž…์˜ ๊ฐ์ฒด๋กœ์จ,
    //   @RequestMapping์ด ๋ถ™์€ ๋ฉ”์†Œ๋“œ์˜ ์ •๋ณด๋ฅผ ์ถ”์ƒํ™”ํ•œ ๊ฐ์ฒด
    default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    	System.out.println("๐Ÿ”น preHandle: ์ปจํŠธ๋กค๋Ÿฌ ์‹คํ–‰ ์ „");
        return true; // false๋ฉด ์ปจํŠธ๋กค๋Ÿฌ๋กœ ๊ฐ€์ง€ ์•Š์Œ
    }
	
    
    // postHandle() ๋ฉ”์†Œ๋“œ
    // - ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ํ˜ธ์ถœ๋œ ํ›„์— ์‹คํ–‰. ์ปจํŠธ๋กค๋Ÿฌ ์ดํ›„์— ์ฒ˜๋ฆฌํ•ด์•ผํ•˜๋Š” ํ›„์ฒ˜๋ฆฌ ์ž‘์—…๋•Œ
    // - ModelAndView ํƒ€์ž…์˜ ์ •๋ณด๊ฐ€ ์ œ๊ณต
    // - ์ตœ๊ทผ์—๋Š” Json ํ˜•ํƒœ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ œ๊ณตํ•˜๋Š” RestAPI๊ธฐ๋ฐ˜์˜ ์ปจํŠธ๋กค๋Ÿฌ(@RestController)๋ฅผ ๋งŒ๋“ค๋ฉด์„œ ์ž์ฃผ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค.
    // - ์ปจํŠธ๋กค๋Ÿฌ ํ•˜์œ„ ๊ณ„์ธต์—์„œ ์ž‘์—…์„ ์ง„ํ–‰ํ•˜๋‹ค๊ฐ€ ์ค‘๊ฐ„์— ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด postHandle์€ ํ˜ธ์ถœ๋˜์ง€ ์•Š์Œ
    default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
        @Nullable ModelAndView modelAndView) throws Exception {
        System.out.println("๐Ÿ”ธ postHandle: ์ปจํŠธ๋กค๋Ÿฌ ์‹คํ–‰ ํ›„, ๋ทฐ ๋ Œ๋”๋ง ์ „");
    }
	
    // afterCompletion() ๋ฉ”์†Œ๋“œ
    // - ๋ชจ๋“  ๋ทฐ์—์„œ ์ตœ์ข…๊ฒฐ๊ณผ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ผ์„ ํฌํ•จํ•ด ๋ชจ๋“  ์ž‘์—…์ด ์™„๋ฃŒ๋œ ํ›„์— ์‹คํ–‰
    // - ์š”์ฒญ ์ฒ˜๋ฆฌ ์ค‘์— ์‚ฌ์šฉํ•œ ๋ฆฌ์†Œ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•  ๋•Œ ์‚ฌ์šฉ
    // - ์ปจํŠธ๋กค๋Ÿฌ ํ•˜์œ„ ๊ณ„์ธต์—์„œ ์ž‘์—… ์ง„ํ–‰ํ•˜๋‹ค๊ฐ€ ์ค‘๊ฐ„์— ์˜ˆ์™ธ ๋ฐœ์ƒํ•˜๋”๋ผ๋„ ๋ฐ˜๋“œ์‹œ ํ˜ธ์ถœ๋จ
    default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
        @Nullable Exception ex) throws Exception {
        System.out.println("โœ… afterCompletion: ๋ทฐ ๋ Œ๋”๋ง ํ›„, ๋ฆฌ์†Œ์Šค ์ •๋ฆฌ");
        if (ex != null) {
            System.out.println("์˜ˆ์™ธ ๋ฐœ์ƒ: " + ex.getMessage());
        }
    }
}

 

  • ์šฉ๋„
    • ์„ธ๋ถ€์ ์ธ ๋กœ๊ทธ์ธ ์ฒดํฌ / ๊ถŒํ•œ ์ธ์ฆ
    • API ํ˜ธ์ถœ ์ „ ๊ฒ€์ฆ
    • ๊ณตํ†ต ๋ฐ์ดํ„ฐ ์‚ฝ์ž… (์˜ˆ: ๋ฉ”๋‰ด ์ •๋ณด)
    • ์„ฑ๋Šฅ ์ธก์ •
    • Controller๋กœ ๋„˜๊ฒจ์ฃผ๋Š” ์ •๋ณด(๋ฐ์ดํ„ฐ)์˜ ๊ฐ€

 


 

 

 

 


(์ฐธ๊ณ  ์‚ฌํ•ญ) ์กฐ๊ธˆ ์˜ค๋ž˜๋œ ์ฑ…๋“ค์„ ๋ณด๋ฉด ํ•„ํ„ฐ(Filter)๋Š” ์„œ๋ธ”๋ฆฟ ๊ธฐ์ˆ ์ด๋ผ์„œ Spring์˜ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•  ์ˆ˜ ์—†์œผ๋ฉฐ ๋นˆ์„ ์ฃผ์ž…๋ฐ›์„์ˆ˜๋„ ์—†๋‹ค๋Š” ๋‚ด์šฉ์ด ๋‚˜์˜ด. ํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด๋ณด๋ฉด Filter ์—ญ์‹œ ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๋“ฑ๋ก์ด ๊ฐ€๋Šฅํ•˜๊ณ , ๋นˆ์˜ ์ฃผ์ž…๋„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

 

 

DelegatingFilterProxy์™€ SpringBoot์˜ ๋“ฑ์žฅ

์Šคํ”„๋ง 1.2๋ถ€ํ„ฐ DelegatingFilterProxy๊ฐ€ ๋‚˜์˜ค๋ฉด์„œ ์„œ๋ธ”๋ฆฟ ํ•„ํ„ฐ ์—ญ์‹œ ์Šคํ”„๋ง์—์„œ ๊ด€๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•ด์ง.

๊ทธ๋ฆฌ๊ณ , ์ด DelegatingFilterProxy๋ฅผ ๋“ฑ๋กํ•˜๋Š” ๊ณผ์ •์€ Spring์ด๊ธฐ ๋•Œ๋ฌธ์— ํ•„์š”ํ•œ ๊ฒƒ์ด๊ณ , SpringBoot๋ผ๋ฉด DelegatingFilterProxy์กฐ์ฐจ ํ•„์š” ์—†๋‹ค!