Spring 숙련
Filter
디스패처 서블릿(Dispatcher Servlet)에 요청이 전달되기 전/후에 url 패턴에 맞는 모든 요청에 대해 부가작업을 처리할 수 있는 기능을 제공한다. 디스패처 서블릿은 스프링의 가장 앞단에 존재하는 프론트 컨트롤러이므로, 필터는 스프링 범위 밖에서 처리가 된다.
javax.servlet의 Filter 인터페이스를 implements 받아 사용한다.
보유 메서드
init()
- 필터 객체를 초기화하고 서비스에 추가, 이후의 작업은 doFilter()에서 이루어짐.
doFilter()
- 필터가 본격적으로 할 작업의 내용을 적음. 필터체인으로 연결하여 필터와 매핑된 URL에 요청이 들어올때마다 doFilter()가 호출됨.
- filterChain은 다음 필터를 가리키고 filterChain.doFilter()는 다음 필터를 호출함. 다음 필터가 없다면 내부적으로 서블릿의 service()를 호출.
destroy()
- 필터가 웹 컨테이너에서 삭제될 때 호출함.
Filter
사용 예제@WebFilter(urlPatterns = "/*") public class PerformanceFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { // 1. 전처리 작업 long startTime = System.currentTimeMillis(); // 2. 서블릿(컨트롤러) 또는 다음 필터 filterChain.doFilter(request, response); // 3. 후처리 작업 long endTime = System.currentTimeMillis(); System.out.print("[" + ((HttpServletRequest)request).getRequestURI() + "]"); System.out.println(" time = " + (endTime - startTime)); // 관심사의 분리 적용 x } }
Interceptor
디스패처 서블릿이 컨트롤러를 호출하기 전/후에 요청과 응답을 참조하거나 가공할 수 있는 기능을 제공한다. 인터셉터는 웹 컨테이너에서 동작하는 필터와 달리 스프링 컨텍스트에서 동작한다.
org.springframework.web.servlet의 HandlerInterceptor 인터페이스를 implements 받아 사용한다.
보유 메서드
preHandle()
- 컨트롤러 이전에 처리해야 하는 전처리 작업이나 요청 정보를 가공하고 추가하는 경우에 사용할 수 있음. 반환타입 boolean으로 반환값이 true면 다음 단계로 진행, false라면 작업을 중단.
postHandle()
- 컨트롤러 이후에 처리해야 하는 후처리 작업이 있을 때 사용할 수 있음.
afterCompletion()
- 모든 뷰에서 최종 결과를 생성하는 등 작업이 완료된 후에 실행됨. 요청 처리 중에 사용한 리소스를 반환할 때 사용하기에 적합.
InterCeptor
사용 예제@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new PerformanceInterceptor()) .addPathPatterns("/**") // 인터셉터 적용 대상 .excludePathPatterns("/css/**", "/js/**"); // 인터셉터 적용 제외대상 } } ----------------- @Component public class PerformanceInterceptor implements HandlerInterceptor { // long startTime; // 1. iv 변수로 저장하거나 (다른 쓰레드에서 값 덮어쓸 수 있음 주의) // long endTime; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { long startTime = System.currentTimeMillis(); request.setAttribute("startTime", startTime); // 2. request 객체에 저장하여 사용 // handler - 요청하고 연결된 컨트롤러의 메서드 HandlerMethod method = (HandlerMethod) handler; System.out.println("method.getMethod() = " + method.getMethod()); // URL과 연결된 메서드 System.out.println("method.getBean() = " + method.getBean()); // 메서드가 포함된 컨트롤러 return HandlerInterceptor.super.preHandle(request, response, handler); } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { long startTime = (long)request.getAttribute("startTime"); long endTime = System.currentTimeMillis(); System.out.print("[" + ((HttpServletRequest)request).getRequestURI() + "]"); System.out.println(" time = " + (endTime - startTime)); HandlerInterceptor.super.postHandle(request, response, handler, modelAndView); } }