서블릿 필터와 리스너란 뭘까?
1. 필터란?
필터(Filter)는 서블릿이나 JSP에 요청이 도달하기 전에 요청과 응답을 가로채서 처리하는 컴포넌트입니다. 필터는 요청을 수정하거나, 응답을 변경하거나, 로깅 및 인증 등의 작업을 수행할 수 있습니다.
필터는 클라이언트와 자원사이에 여러개의 필터가 모여서 하나의 체인(Chain)을 형성할수 도 있습니다.
WAS 서버에 필터를 설정하는 방법은 web.xml 파일에서 설정하거나 자바 코드측에 애노테이션을 사용하여 설정할 수 있는 방법이 존재 합니다.
예시 코드 - web.xml 파일에 설정 가능
예시 코드 - java 파일에 설정 가능
필터의 주요 기능
- 요청 및 응답의 전처리 및 후처리
- 로깅 처리
- 인증 및 권한 부여
- 데이터 압축
서블릿 리스너
리스너란?
컨테이너에서 발생하는 이벤트를 모니터링하다가 특정 이벤트가 발생하면 실행되는 특수한 서블릿으로, '이벤트 리스너'라고도 한다. 즉, 리스너는 웹 애플리케이션에서 특정한 사건이 일어났을 때 그것을 알아차리고 적절한 처리를 하는 역할을 합니다. 예를 들어 애플리케이션이 시작되거나 종료될 때 발생하는 사건 이나 사용자가 웹사이트에 로그인하거나 로그아웃하는 등의 사건 또는 사용자가 웹페이지를 요청하거나 특정 작업을 수행할 때 발생하는 사건 등 리스너는 이러한 다양한 사건들을 감지하고, 필요한 작업을 자동으로 수행하는 중요한 역할을 합니다.
WAS 서버에 리스너를 설정하는 방법은 서블릿과 마찬가지로 web.xml 파일에서 설정하거나 자바 코드측에 애노테이션을 사용하여 설정할 수 있는 방법이 존재 합니다.
web.xml 파일에 설정 방식
<web-app ..>
<listener>
<listener-class>com.example.AppContextListener</listener-class>
</listener>
</web-app>
자바코드 애노테이션으로 설정하는 방식
@WebListener
public class AppContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
// 애플리케이션 시작 시 처리 작업
System.out.println("Application started at " + new java.util.Date());
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
// 애플리케이션 종료 시 처리 작업
System.out.println("Application stopped at " + new java.util.Date());
}
}
리스너의 주요 기능
- 애플리케이션 시작 및 종료 감지
- 세션 생성 및 소멸 감지
- 요청 시작 및 종료 감지
- 애플리케이션 속성 변경 감지
시나리오 코드 1
프로젝트 생성 - filterListenerEx
package com.tenco.filters;
import java.io.IOException;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
/**
* 1. Filter 구현
* 2. URL 패턴 설정 (web.xml 파일에서 설정할 예정)
*/
public class IPBlockFilter implements Filter {
// 192.168.0.48 <-- 내 아이피
// http://192.168.0.48:8080/fl/home
// 차단할 IP 대역의 접두사
private static final String BLOCKED_IP_PREFIX = "192.168.0";
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("IPBlockFilter 초기화 ");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 전처리 - 요청자에 IP를 확인
String remoteIP = request.getRemoteAddr();
System.out.println("Request from IP : " + remoteIP);
// 차단 시킬 IP 코드 작성
if(remoteIP.startsWith(BLOCKED_IP_PREFIX)) {
response.setContentType("text/plain;charset=UTF-8");
response.getWriter().println("Access Denied !!");
response.getWriter().println("너는 못 지나간다~~");
return;
}
chain.doFilter(request, response);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://jakarta.ee/xml/ns/jakartaee"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
id="WebApp_ID" version="6.0">
<display-name>filterListenerEx</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.jsp</welcome-file>
<welcome-file>default.htm</welcome-file>
</welcome-file-list>
<filter>
<filter-name>IPBlockFliter</filter-name>
<filter-class>com.tenco.filters.IPBlockFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>IPBlockFliter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<description></description>
<display-name>HomeServlet</display-name>
<servlet-name>HomeServlet</servlet-name>
<servlet-class>com.tenco.controller.HomeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HomeServlet</servlet-name>
<url-pattern>/HomeServlet</url-pattern>
</servlet-mapping>
</web-app>
2. 리스너란?
리스너는 특정 이벤트가 발생했을 때 이를 감지하고, 그에 대응하는 작업을 수행하는 자바 객체입니다. 리스너는 서블릿 컨테이너에서 발생하는 다양한 이벤트를 처리할 수 있습니다.
사용하는 이유?
리스너는 웹 애플리케이션의 상태 변화(예: 시작, 종료, 세션 생성 및 소멸)를 감지하여 다음과 같은 작업을 수행할 수 있도록 도와줍니다.
- 초기화 작업 (애플리케이션 시작 시 필요한 리소스 로드)
- 정리 작업 (애플리케이션 종료 시 리소스 해제)
- 세션 관련 작업 (로그인/로그아웃 로깅, 세션 속성 변경 감지)
주요 리스너 인터페이스
- ServletContextListener: 애플리케이션 시작 및 종료 이벤트를 처리합니다.
- HttpSessionListener: 세션 생성 및 소멸 이벤트를 처리합니다.
- ServletRequestListener: 요청 객체의 생성 및 소멸 이벤트를 처리합니다.
AppLifecycleListener
MySessionListener