ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

Spring

[Spring] Filter vs. Interceptor

snail voyager 2020. 5. 19. 10:44
728x90
๋ฐ˜์‘ํ˜•

Filter (javax.servlet.Filter)

๐Ÿ”น ์—ญํ• 

  • ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์š”์ฒญ๊ณผ ์‘๋‹ต์„ ๊ฐ€๋กœ์ฑ„๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
  • ์ฃผ๋กœ ๋ณด์•ˆ, ์ธ์ฝ”๋”ฉ, ๋กœ๊น…, ์ธ์ฆ, ๊ถŒํ•œ ๊ฒ€์‚ฌ ๋“ฑ์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • ์„œ๋ธ”๋ฆฟ ์ปจํ…Œ์ด๋„ˆ ๋ ˆ๋ฒจ์—์„œ ๋™์ž‘ํ•˜๋ฉฐ, DispatcherServlet ์•ž์—์„œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

๐Ÿ”น ๋™์ž‘ ๋ฐฉ์‹

  1. ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด Filter๊ฐ€ ๊ฐ€์žฅ ๋จผ์ € ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
  2. ํ•„ํ„ฐ์—์„œ ์š”์ฒญ์„ ๋ณ€ํ˜•ํ•˜๊ฑฐ๋‚˜, ๋กœ๊น… ๋“ฑ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  3. chain.doFilter(request, response)๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋‹ค์Œ ํ•„ํ„ฐ ๋˜๋Š” ์„œ๋ธ”๋ฆฟ์œผ๋กœ ์š”์ฒญ์ด ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.
  4. ์‘๋‹ต์ด ์ƒ์„ฑ๋˜๋ฉด ๋‹ค์‹œ Filter์—์„œ ์‘๋‹ต์„ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter("/*")  // ๋ชจ๋“  ์š”์ฒญ์— ๋Œ€ํ•ด ์ ์šฉ
public class MyFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
            throws IOException, ServletException {
        System.out.println("์š”์ฒญ์ด ํ•„ํ„ฐ๋ฅผ ํ†ต๊ณผํ•ฉ๋‹ˆ๋‹ค.");
        
        // ๋‹ค์Œ ํ•„ํ„ฐ ๋˜๋Š” ์ปจํŠธ๋กค๋Ÿฌ๋กœ ์š”์ฒญ ์ „๋‹ฌ
        chain.doFilter(request, response);
        
        System.out.println("์‘๋‹ต์ด ํ•„ํ„ฐ๋ฅผ ํ†ต๊ณผํ•ฉ๋‹ˆ๋‹ค.");
    }
}

๐Ÿ”น Filter์˜ ํŠน์ง•

  • DispatcherServlet ์ด์ „์— ์‹คํ–‰๋จ
  • Spring๊ณผ ๊ด€๊ณ„์—†์ด ์„œ๋ธ”๋ฆฟ ๋ ˆ๋ฒจ์—์„œ ๋™์ž‘
  • URL ํŒจํ„ด์„ ๊ธฐ์ค€์œผ๋กœ ์ ์šฉ ๊ฐ€๋Šฅ
  • ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ•„ํ„ฐ๋ฅผ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ˆœ์„œ๋ฅผ ์กฐ์ • ๊ฐ€๋Šฅ

Interceptor (HandlerInterceptor)

๐Ÿ”น ์—ญํ• 

  • Spring MVC์—์„œ ์ปจํŠธ๋กค๋Ÿฌ์˜ ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑ„๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
  • ์ฃผ๋กœ ๋กœ๊ทธ์ธ ์ฒดํฌ, ์ธ์ฆ, ๊ถŒํ•œ ๊ฒ€์‚ฌ, ๋กœ๊น… ๋“ฑ์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • DispatcherServlet์ด ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์ „ํ›„์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

๐Ÿ”น ๋™์ž‘ ๋ฐฉ์‹

  1. ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด preHandle()์ด ์‹คํ–‰๋จ → ์ปจํŠธ๋กค๋Ÿฌ ์‹คํ–‰ ์—ฌ๋ถ€ ๊ฒฐ์ • ๊ฐ€๋Šฅ
  2. ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ์‹คํ–‰๋จ
  3. ์ปจํŠธ๋กค๋Ÿฌ ์‹คํ–‰ ํ›„ postHandle()์ด ์‹คํ–‰๋จ → ๋ชจ๋ธ ๋ฐ์ดํ„ฐ ์ˆ˜์ • ๊ฐ€๋Šฅ
  4. ๋ทฐ๊ฐ€ ๋ Œ๋”๋ง๋œ ํ›„ afterCompletion()์ด ์‹คํ–‰๋จ → ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๋ฐ ๋ฆฌ์†Œ์Šค ์ •๋ฆฌ
import org.springframework.web.servlet.HandlerInterceptor;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

public class MyInterceptor implements HandlerInterceptor {
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 
            throws Exception {
        System.out.println("Interceptor: ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑ•๋‹ˆ๋‹ค.");
        return true;  // true: ์š”์ฒญ์„ ์ปจํŠธ๋กค๋Ÿฌ๋กœ ๋ณด๋ƒ„, false: ์š”์ฒญ ์ฐจ๋‹จ
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, 
                           ModelAndView modelAndView) throws Exception {
        System.out.println("Interceptor: ์ปจํŠธ๋กค๋Ÿฌ ์‹คํ–‰ ํ›„");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, 
                                Exception ex) throws Exception {
        System.out.println("Interceptor: ๋ทฐ ๋ Œ๋”๋ง ํ›„");
    }
}


import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor())
                .addPathPatterns("/api/**")  // ํŠน์ • ๊ฒฝ๋กœ์—๋งŒ ์ ์šฉ
                .excludePathPatterns("/login", "/signup");  // ์˜ˆ์™ธ ๊ฒฝ๋กœ ์„ค์ •
    }
}

๐Ÿ”น Interceptor์˜ ํŠน์ง•

  • DispatcherServlet ์ดํ›„์— ์‹คํ–‰๋จ
  • Spring MVC์—์„œ ๋™์ž‘ํ•˜๋ฉฐ, HandlerMapping์„ ํ†ตํ•ด ์ปจํŠธ๋กค๋Ÿฌ ๋‹จ์—์„œ ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑ”
  • addPathPatterns() ๋ฐ excludePathPatterns()์„ ์‚ฌ์šฉํ•˜์—ฌ ํŠน์ • URL ํŒจํ„ด์—๋งŒ ์ ์šฉ ๊ฐ€๋Šฅ
  • preHandle()์—์„œ ์š”์ฒญ์„ ์ฐจ๋‹จํ•  ์ˆ˜๋„ ์žˆ์Œ

Filter vs Interceptor

๊ตฌ๋ถ„ Filter Interceptor
์‹คํ–‰ ์œ„์น˜ DispatcherServlet ์ด์ „ DispatcherServlet ์ดํ›„
๋™์ž‘ ์ˆ˜์ค€ ์„œ๋ธ”๋ฆฟ ์ˆ˜์ค€ (Spring๊ณผ ๋ฌด๊ด€) Spring MVC ์ˆ˜์ค€ (HandlerMapping ์ดํ›„)
์ฃผ ์‚ฌ์šฉ ๋ชฉ์  ๋ณด์•ˆ, ์ธ์ฝ”๋”ฉ, ๋กœ๊น…, ์š”์ฒญ ์ˆ˜์ • ์ธ์ฆ, ๊ถŒํ•œ ๊ฒ€์‚ฌ, ๋กœ๊น…, ๋ฐ์ดํ„ฐ ์กฐ์ž‘
์š”์ฒญ ์ฐจ๋‹จ ๊ฐ€๋Šฅ doFilter()์—์„œ ๊ฐ€๋Šฅ preHandle()์—์„œ ๊ฐ€๋Šฅ
์„ค์ • ๋ฐฉ์‹ @WebFilter ๋˜๋Š” FilterRegistrationBean addInterceptors() ์‚ฌ์šฉ

์–ธ์ œ ๋ฌด์—‡์„ ์‚ฌ์šฉํ• ๊นŒ?

  • ์ „์—ญ์ ์œผ๋กœ ๋ชจ๋“  ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑ„์•ผ ํ•œ๋‹ค๋ฉด → Filter
    • ์˜ˆ: CORS ์„ค์ •, ์ธ์ฝ”๋”ฉ ๋ณ€ํ™˜, ๊ณตํ†ต ๋กœ๊น…, ์š”์ฒญ/์‘๋‹ต ๋ณ€์กฐ
  • Spring MVC์—์„œ ํŠน์ • ์ปจํŠธ๋กค๋Ÿฌ ๋กœ์ง ์ „ํ›„๋ฅผ ๊ฐ€๋กœ์ฑ„์•ผ ํ•œ๋‹ค๋ฉด → Interceptor
    • ์˜ˆ: ๋กœ๊ทธ์ธ ์—ฌ๋ถ€ ํ™•์ธ, JWT ์ธ์ฆ, API ์š”์ฒญ ๋กœ๊น…

์‹คํ–‰ ์ˆœ์„œ ์š”์•ฝ (Spring MVC ๊ธฐ์ค€)

๋‹จ๊ณ„ ์‹คํ–‰ ์ฃผ์ฒด ์„ค๋ช…
1๏ธโƒฃ Filter DispatcherServlet ์ด์ „ (Servlet ์ŠคํŽ™)
2๏ธโƒฃ Interceptor (preHandle) Controller ํ˜ธ์ถœ ์ „
3๏ธโƒฃ @Aspect (Around / Before) ๋ฉ”์„œ๋“œ ๋ ˆ๋ฒจ AOP ์ง„์ž…
4๏ธโƒฃ Controller ์‹ค์ œ ๋กœ์ง ์‹คํ–‰
5๏ธโƒฃ @Aspect (After / AfterReturning / AfterThrowing) Controller ๋ฉ”์„œ๋“œ ์ข…๋ฃŒ ์ดํ›„
6๏ธโƒฃ Interceptor (postHandle / afterCompletion) ์‘๋‹ต ์ง์ „, ๋ทฐ ๋ Œ๋”๋ง ์ดํ›„
7๏ธโƒฃ ResponseBodyAdvice (if applicable) JSON ๊ฐ€๊ณต ๋“ฑ ์‘๋‹ต ์ปค์Šคํ„ฐ๋งˆ์ด์ง•

Interceptor์—์„œ return false๋ฅผ ํ•˜๊ฒŒ ๋˜๋ฉด

์ปจํŠธ๋กค๋Ÿฌ๋Š” ์‹คํ–‰๋˜์ง€ ์•Š๊ณ , ์ดํ›„ ๋กœ์ง์ด ์ค‘๋‹จ๋ฉ๋‹ˆ๋‹ค.

์‘๋‹ต์€ ์ง์ ‘ ์ž‘์„ฑํ•ด์ฃผ์ง€ ์•Š์œผ๋ฉด ์•„๋ฌด ๋‚ด์šฉ ์—†์ด ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค.

return false๋งŒ ํ•˜๊ณ  ์‘๋‹ต์„ ์ž‘์„ฑํ•˜์ง€ ์•Š์œผ๋ฉด โŒ ๋ธŒ๋ผ์šฐ์ €๋Š” ์‘๋‹ต์ด ์—†๊ฑฐ๋‚˜ ๋นˆ ํŽ˜์ด์ง€๋กœ ๋ณด์ž„
์‘๋‹ต์ด ์—†๋Š”๋ฐ๋„ ์ƒํƒœ์ฝ”๋“œ๊ฐ€ 200์ผ ์ˆ˜๋„ ์žˆ์Œ โ›” ํด๋ผ์ด์–ธํŠธ ์ž…์žฅ์—์„œ ํ˜ผ๋ž€ ๋ฐœ์ƒ
์ฆ‰์‹œ ์ข…๋ฃŒ๋˜๊ธฐ ๋•Œ๋ฌธ์— postHandle, afterCompletion, AOP, Controller ๋“ฑ ์ „๋ถ€ ์‹คํ–‰๋˜์ง€ ์•Š์Œ ๐Ÿ”’ ์™„์ „ ์ค‘๋‹จ๋จ
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    if (isInvalidRequest()) {
        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
        response.setContentType("application/json;charset=UTF-8");

        String body = new ObjectMapper().writeValueAsString(Map.of(
            "status", 403,
            "message", "์ž˜๋ชป๋œ ์š”์ฒญ์ž…๋‹ˆ๋‹ค."
        ));

        response.getWriter().write(body);
        return false;
    }

    return true;
}

 

 

 

https://mangkyu.tistory.com/173

728x90
๋ฐ˜์‘ํ˜•

'Spring' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

Spring ApplicationContextInitializer  (0) 2022.01.11
Request Content-Type์— ๋”ฐ๋ฅธ ๋ฐ์ดํ„ฐ ์ „์†ก ๋ฐฉ์‹  (0) 2020.06.12
Session, Cookie  (0) 2020.05.18
Spring MVC  (0) 2020.05.16
Spring JDBC (Java DataBase Connection)  (0) 2020.05.16
๋ฐ˜์‘ํ˜•
300x250