코드프레소 백엔드 개발자 양성 과정
서블릿의 필터와 리스너
서블릿의 필터와 리스너에 대해 알아보고 둘의 차이점 또한 파악해 보겠다.
필터란?
필터란 서블릿과 브라우저 간에 요청이나 응답이 이뤄질 때 미리 여러 가지 작업을 처리하는 기능이다. 이는 여러 서블릿에서 반복적으로 수행해야 하는 작업을 공통으로 처리할 수 있다는 장점을 지닌다.
가령 웹 페이지에서 입력한 한글을 서블릿에 전달하려면 setCharacterEncoding()
메서드를 각각의 서블릿마다 구현해주어야 한다.
하지만 필터를 이용하게 되면 서블릿 내부에서 이뤄지던 인코딩 기능을 밖으로 빼내어 클라이언트로부터 서블릿에 도달하기 전에 인코딩 작업이 수행된다. 이는 서블릿에서 클라이언트 측으로 응답이 반환될 때도 똑같이 작동한다.
필터를 이용한 구조에서는 특정 기능이 분리되고 모듈화되었다는 점에서 가독성과 재사용성이 향상되며 유지 및 보수 또한 용이하게 된다.
클라이언트와 서블릿 사이에서 작동하는 객체인 만큼 필터에는 두 가지 종류가 있다.
- 요청 필터 : 사용자 인증, 요청 관련 로그 작업, 인코딩
- 응답 필터 : 응답 결과 암호화, 서비스 시간 측정
필터 관련 자바 API로는 아래와 같은 것들이 있다.
javax.servlet.Filter
javax.servlet.FilterChain
javax.servlet.FilterConfig
리스너란?
리스너란 특정 이벤트가 발생하기를 ‘귀 기울여’ 기다리다가 실행되는 메서드나 함수, 혹은 그 메서드를 지닌 객체를 가리킨다. 생소한 개념일 수도 있는 이벤트는 이 맥락에서는 발생한 특정 사건을 뜻한다. 마우스 클릭, 키보드 입력, 클라이언트로부터의 HTTP 요청, 웹 애플리케이션 시작, 종료 등이 그 예이다.
서블릿 관련 리스너 종류의 실례를 들자면 세션 객체 생성이나 소멸 시 처리되는 HttpSessionListener
나 세션에 바인딩된 객체를 알려주는 이벤트 발생 시 작동하는 HttpSessionBindingListener
등이 있다.
여기서 리스너와 필터의 차이가 궁금해질 수도 있다. 분명 한 번 설정을 해두면 개발자가 매번 새로 코드를 입력하지 않아도 자동으로 실행된다는 점은 같다.
하지만 둘의 차이는 필터와 리스너의 개념을 떠올리면 뚜렷해진다. 필터는 클라이언트와 서블릿 사이에서 작업을 미리 수행하는 반면 리스너는 오가는 요청이나 응답에 관계 없이 특정 이벤트에 의해 실행된다.
필터와 리스너의 관계가 정립이 되었다면 접속 중인 사용자의 수를 반환하는 리스너를 구현해본다.
우선 LoginTest
라는 클래스를 하나 만들어 전송된 ID와 비밀번호를 저장하는 객체를 만든다.
여기서 session.setAttribute()
메서드로 세션에 바인딩 시 HttpSessionBindingListener
를 구현한 LoginImpl
이라는 클래스에서 valueBound()
메서드가 호출된다.
위와 같이 LoginImpl
이라는 클래스는 HttpSessionBindingListener
를 구현하여 세션에 바인딩이 이뤄질 때마다 valueBound()
메서드로 변수인 total_user
의 값을 1씩 증가시킨다.
브라우저에서 로그인 창에 로그인한 결과 접속자수가 실제로 반영되어 표기됨을 볼 수 있다.
이렇게 필터와 리스너를 각각 알아보고 실습도 해보았다. 이와 같은 API를 사용하면 반복적인 절차를 간소화하고 웹 서비스를 더 고급스럽게 구현할 수 있다.
참고 : 자바 웹을 다루는 기술 (이병승)