패스트캠퍼스 남궁성님 강의 보고 정리하였습니다
filter란?
공통적인 요청 전처리와 응답 후처리에 사용됨(로깅, 인코딩 등)
- 여러 서블릿들에서 위의 그림처럼, 공통적으로 발생하는 전처리, 후처리를 필터를 통해 중복 제거가 가능
- 따라서 서블릿들에서는 본래의 맡은 처리만 즉 하나의 책임만 가질 수 있게 됨
filter의 처리 과정
아래의 과정을 거쳐 요청이 처리된다고 할때 ( ->)
처리되는 과정은 다음과 같다.
- 요청이 오면 처음 filter1의 전처리 진행
- filter2 호출
- filter2 전처리
- 서블릿 호출 후 메서드 처리
- filter2 후처리
- filter1 후처리
filter의 사용 예시
아래와 같은 서블릿이 있을 때, 전처리, 후처리 등 분리해야 할 코드가 보인다.
- ExampleServlet.java
@WebServlet("/abc")
public class ExampleServlet extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response) {
// 1. 전처리 작업
long startTime = System.currentTimeMillis();
// 2. 작업 로직
// 3. 후처리 작업
System.out.print("time = " + (System.cuurentTimeMillis() - startTime) + "ms");
}
}
위와 같은 서블릿에서 전처리, 후처리 작업을 분리할 필터 예시는 아래와 같다.
- PerformanceFilter.java
@WebFilter(urlPatterns = "/*") // 모든 요청에 PerformanceFilter를 적용.
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));
}
Interceptor란?
쉽게 말해 servlet이 발전한 것이 controller라면, filter가 발전한 것이 Interceptor라고 생각하면 된다.
Interceptor 코드를 통해 이해하기
- HandlerInterceptor를 implements한 후에
- preHandle(전처리), postHandle(후처리) 메서드를 구현
- @Component 어노테이션을 통해 컴토넌트 등록
@Component
public class PerformanceInterceptor implements HandlerInterceptor {
// long startTime; // 인스턴스 변수임 -> 싱글톤(하나의 객체라) 여러 쓰레드가 하나의 객체를 공유
// 따라서 지역 변수 보다는 request에 저장해서 공유하는 것이 낫다
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 1. 전처리
long startTime = System.currentTimeMillis();
request.setAttribute("startTime", startTime);
// handler - 요청하고 연결된 컨트롤러의 메서드
HandlerMethod method = (HandlerMethod) handler;
System.out.println("method.getMethod() = " + method.getMethod()); // URL하고 연결된 메서드
System.out.println("method.getBean() = " + method.getBean()); // 메서드가 포함된 컨트롤러
// true를 리턴하면 다음 인터셉터 또는 컨트롤러가 호출
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");
// 2. 후처리
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
4. WebMvcConfigurer를 implements한 @Configuration 클래스를 생성하고
5. addInterceptors를 오버라이딩하여 해당 Interceptors를 추가해주면 됨!
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new PerformanceInterceptor())
.addPathPatterns("/**") // 인터셉터를 적용할 대상
.excludePathPatterns("/css/**", "/js/**"); // 인터셉터 적용 제외대상
}
}
filter와 Interceptor의 차이점
Interceptor가 filter에서 발전한 것은 알겠으나, 구체적으로 무엇이 다를까?
filter는 servletContext에 위치한 반면,
Interceptor는 WebApplicationContext에 위치하였는데 때문에 같은 WebApplicationContext에 있는 다른 Bean(자바 객체)들에 접근이 가능하다!
'Spring 🟢' 카테고리의 다른 글
LazyConnectionDataSourceProxy에 대해 알아보자 (0) | 2024.10.25 |
---|---|
[Spring] 시큐리티로 JWT 로그인 구현하기 (0) | 2023.10.20 |
[JPA] 기본키 매핑(IDENTITY, SEQUENCE 전략) (0) | 2023.08.11 |
[Spring] RowMapper (2) | 2023.06.09 |
[Intellij] Cause: error: invalid source release: 16 해결하기 (0) | 2023.06.02 |