개발/Java & Kotlin

[Spring] Filter, Interceptor

devhooney 2022. 7. 10. 15:13
728x90

스프링 시큐리티를 공부하면서 필터, 인터셉터에 대해 더 자세한 공부를 하게 됐다.

https://goddaehee.tistory.com/154

클라이언트에서 요청이 있을 경우

Filter -> InterCeptor -> AOP -> InterCeptor -> FIlte이다.

 

1. 서버를 실행시켜 서블릿이 올라오는 동안 init() 실행, 그 후 doFilter() 실행

2. Controller에 들어가기 전 preHandler 실행

3. Controller에서 나와 postHandler, after Completion, doFilter 순으로 진행

4. 서블릿 종료 시 destory가 실행

 

Filter

- 필터는 요청과 응답을 한번 필터링 해주는 역할

- 필터는 스프링 컨텍스트 외부에 존재

- 인코딩 변환처리, xss방어 들의 요청에 대한 처리로 사용된다.

- 필터의 실행 메소드

1. init(): 필터 인스턴스 초기화

- init 메소드는 필터 객체를 초기화하고 서비스에 추가하기 위한 메소드

- 웹 컨테이너가 1회 init 메소드를 호출하여 필터 객체를 초기화하면 이후의 요청들은 doFilter를 통해 처리

 

2. doFilter(): 전, 후 처리

- doFilter 메소드는 url-pattern에 맞는 모든 HTTP 요청이 디스패처 서블릿으로 전달되기 전에 웹 컨테이너에 의해 실행되는 메소드

- doFilter의 파라미터로는 FilterChain이 있는데, FilterChain의 doFilter 통해 다음 대상으로 요청을 전달

- chain.doFilter() 전/후에 우리가 필요한 처리 과정을 넣어줌으로써 원하는 처리를 진행

 

3. destory(): 필터 인스턴스 종료

- destroy 메소드는 필터 객체를 서비스에서 제거하고 사용하는 자원을 반환하기 위한 메소드

- destroy 메소드는 웹 컨테이너에 의해 1번 호출되며 이후에는 이제 doFilter에 의해 처리되지 않는다.

 

Interceptor

- 요청에 대한 작업 전/후로 사전 작업해주는 역할

- 인터셉터는 스프링의 DispatcherServlet이 Controller를 호출하기 전, 후에 동작

- 여러개 사용 가능

- 로그인 확인, 권한 확인, 프로그램 실행  시간 계산 작업 로그확인 등의 업무 처리로 사용된다.

- 인터셉터의 실행 메소드

1. preHandler():  Controller 메소드가 실행 되기 전

- preHandle 메소드는 Controller가 호출되기 전에 실행

- Controller 이전에 처리해야 하는 전처리 작업이나 요청 정보를 가공하거나 추가하는 경우에 사용

- preHandle의 3번째 파라미터인 handler 파라미터는 핸들러 매핑이 찾아준 Controller 빈에 매핑되는 HandlerMethod라는 새로운 타입의 객체로써, @RequestMapping이 붙은 메소드의 정보를 추상화한 객체이다.

- preHandle의 반환 타입은 boolean인데 반환값이 true이면 다음 단계로 진행이 되지만, false라면 작업을 중단하여 이후의 작업(다음 인터셉터 또는 컨트롤러)은 진행되지 않는다.

 

2. postHandler(): Controller 메소드 실행 직 후 view 렌더링 전

- postHandle 메소드는 컨트롤러를 호출된 후에 실행

- Controller 이후에 처리해야 하는 후처리 작업이 있을 때 사용

- postHandle 메소드에는 컨트롤러가 반환하는 ModelAndView 타입의 정보가 제공되는데, 최근에는 Json 형태로 데이터를 제공하는 RestAPI 기반의 Controller(@RestController)를 만들면서 자주 사용되지는 않는다.

 

3. afterCompletion(): view 렌더링 후

- afterCompletion 메소드는 이름 그대로 모든 뷰에서 최종 결과를 생성하는 일을 포함해 모든 작업이 완료된 후에 실행

- 요청 처리 중에 사용한 리소스를 반환할 때 사용하기에 적합함

 

필터(Filter) vs 인터셉터(Interceptor) 차이 및 용도

- 필터와 인터셉터는 각각이 관리되는 컨테이너와 Request/Response의 조작가능 여부가 다르고, 그에 따라 용도가 다르다.

- Request/Response 객체 조작 가능 여부

public SampleFilter implements Filter {

    public void doFilter(ServletRequest request
    	, ServletResponse response
        , FilterChain chain) {
        // 필터가 다음 필터를 호출하기 위해서는 필터 체이닝(다음 필터 호출)을 해주어야 한다.
        chain.doFilter(request, response);       
    }
    
}

- 필터는 Request와 Response를 조작할 수 있지만 인터셉터는 조작할 수 없다. 

public class SampleInterceptor implements HandlerInterceptor {

    default boolean preHandle(HttpServletRequest request
    	, HttpServletResponse response
        , Object handler) {
        // Request/Response를 교체할 수 없고 boolean 값만 반환할 수 있다.
        return true;
    }

}

- 디스패처 서블릿이 여러 인터셉터 목록을 가지고 있고, for문으로 순차적으로 실행

- true를 반환하면 다음 인터셉터가 실행되거나 컨트롤러로 요청이 전달되며, false가 반환되면 요청이 중단

 

- 필터(Filter)의 용도 및 예시

1. 공통된 보안 및 인증/인가 관련 작업

2. 모든 요청에 대한 로깅 또는 감사

3. 이미지/데이터 압축 및 문자열 인코딩

4. Spring과 분리되어야 하는 기능

 

- 인터셉터(Interceptor)의 용도 및 예시

1. 세부적인 보안 및 인증/인가 공통 작업

2. API 호출에 대한 로깅 또는 감사

3. Controller로 넘겨주는 정보(데이터)의 가공

 

 

 

출처

https://mangkyu.tistory.com/173

https://goddaehee.tistory.com/154

728x90

'개발 > Java & Kotlin' 카테고리의 다른 글

[JPA] 기본 영속성 관리 - 내부 동작 방식  (0) 2022.07.11
[Java] 재귀 알고리즘  (0) 2022.07.11
[Java] 스택과 큐  (0) 2022.07.10
[Java] 검색  (0) 2022.07.10
[Java] 기본 자료구조  (0) 2022.07.08