다시 정문 앞에서 #
1화에서는 손님(요청) 하나가 회사 건물(서버)에 들어와 경비실, 안내데스크, 접수창구, 담당 직원 순으로 네 개의 관문을 지난다고 정리했다. 이번 화는 첫 번째 관문인 경비실 이야기다. 기술 용어로는 Filter다.
아직 아무도 만나기 전이다 #
손님이 정문에 도착했다. 경비원은 이 손님이 몇 층 몇 부서를 찾아왔는지 모른다. 관심도 없다. 경비원이 확인하는 건 딱 하나, "이 사람을 건물 안에 들여보내도 되는가"뿐이다.
Filter도 똑같다. 요청이 들어오면 이 요청이 어떤 컨트롤러로 갈지, 어떤 로직을 태울지 아직 정해지지 않은 시점에서 먼저 일한다. 그래서 Filter는 "이 요청을 어떤 화면에서 보냈는지"처럼 스프링이 알아서 해석해주는 정보에는 접근할 수 없다. 딱 손님의 겉모습, 즉 요청과 응답 그 자체만 만질 수 있다.
경비실 명찰에는 다른 회사 이름이 적혀 있다 #
1화에서 흘렸던 이야기를 여기서 풀어본다. 경비실은 이 회사 정직원이 아니라 건물 전체를 관리하는 시설관리 업체 소속이다. 기술적으로 옮기면 Filter는 스프링이 만든 개념이 아니라 Jakarta Servlet 스펙(jakarta.servlet.Filter)에 정의된 개념이다. 관리 주체도 스프링이 아니라 톰캣 같은 WAS(웹 애플리케이션 서버)다.
그래서 Filter는 스프링 컨텍스트 바깥에 있다. 스프링이 만들어둔 빈(bean)을 마음대로 가져다 쓰기가 까다롭고, 반대로 스프링을 아예 몰라도 동작한다. 시설관리 업체 소속 경비원이 어느 회사가 그 건물에 입주해 있든 신경 안 쓰고 똑같은 방식으로 정문을 지키는 것과 같다. 이렇게 재사용하기 쉬운 덕분에 Filter는 문자 인코딩 처리나 CORS 설정처럼 스프링 로직과 무관한 일을 맡기에 알맞다.
통과시키거나, 고쳐서 들여보내거나 #
경비원이 하는 일은 단순히 통과/차단만은 아니다. 필요하면 손님 소지품을 다른 통에 옮겨 담아 들여보내기도 한다. Filter도 마찬가지다.
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)doFilter 메서드 안에서 chain.doFilter(request, response)를 호출하는 순간이 "다음 관문으로 손님을 넘긴다"는 뜻이다. 이 호출 앞에 코드를 쓰면 손님이 안으로 들어가기 전에 할 일이고, 호출 뒤에 코드를 쓰면 손님이 볼일을 마치고 나가는 길에 할 일이다. 실제로 요청 인코딩을 통일하는 필터, 요청이 들어온 시각을 기록하는 로깅 필터가 이 앞뒤 구조를 그대로 쓴다.
경비원은 한 명이 아니고, 그 위에 검색대도 있다 #
큰 건물이면 정문 경비원이 한 명일 리 없다. 소지품 검사하는 사람, 방문증 나눠주는 사람이 순서대로 늘어서 있다. Filter도 여러 개를 체인으로 엮을 수 있고, 그 순서를 개발자가 지정한다. 앞선 필터를 통과해야 다음 필터로 넘어가는 구조다.
그리고 이 경비실 개념 위에 통째로 세워진 게 있다. 바로 Spring Security다. 로그인 여부를 확인하고 권한 없는 요청을 걸러내는 이 보안 시스템은 사실 여러 개의 보안 필터가 체인으로 쌓인 결과물이다. 즉 담당 직원(컨트롤러)을 만나기도 전에 정문 검색대에서 인증·인가를 이미 끝내놓는다는 뜻이다. Spring Security 자체는 이후 시리즈에서 다루지 않지만, 그 기반이 바로 이번 화의 Filter라는 점은 짚고 넘어갈 만하다.
그래서 이게 왜 중요한데 #
실무에서 이 구분이 쓸모 있는 순간도 둘로 나뉜다.
하나는 로직을 어디에 넣을지 정할 때다. 인코딩 통일, 요청 로깅, CORS 처리처럼 스프링 빈이 굳이 필요 없는 일은 Filter에서 끝내는 게 맞다. 반대로 로그인한 사용자 정보를 스프링이 관리하는 객체에서 꺼내 써야 하는 일이라면 Filter는 애초에 손을 대기 어려운 자리다. 이건 4화에서 다룰 Interceptor의 몫이다.
다른 하나는 디버깅이다. 요청이 컨트롤러까지 오지도 못하고 막혔다면, 십중팔구 Filter 단계다. 인코딩이 깨졌거나 CORS 헤더가 빠졌거나 보안 필터에서 인증 실패로 걸린 경우가 대부분이다. 반대로 로그가 컨트롤러 코드까지 잘 찍힌다면 최소한 정문은 무사히 통과했다는 뜻이다.
다음 화 예고 #
3화에서는 경비실을 통과한 손님이 마주치는 로비 안내데스크, DispatcherServlet을 다룬다. 모든 손님이 예외 없이 거쳐야 하는 단일 창구가 왜 필요한지, 그리고 그 창구가 실제로 무슨 일을 하는지를 짚어본다.
