# (서블릿) 필터란 ?
애노테이션(Annotations)은 Java 언어의 기능으로, 코드에 메타데이터를 추가하여 컴파일러나 프레임워크에게
특정 동작을 하도록 지시할 수 있습니다.
서블릿에서 애노테이션을 사용하면 해당 서블릿을 실행할 때 부가적인 기능을 부여할 수 있습니다.
이것을 필터(Filter)를 통해 조절할 수 있습니다.
예를 들어, 서블릿 애노테이션을 사용하여 특정 URL 패턴과 서블릿 클래스를 연결하면,
해당 URL로 요청이 들어올 때 그에 맞는 서블릿이 실행됩니다.
필터를 사용하면 서블릿 실행 전후에 부가적인 작업을 할 수 있습니다.
이를 통해 로깅, 보안, 데이터 변환 등의 작업을 처리할 수 있습니다.
요약하면:
애노테이션: 서블릿 클래스에 애노테이션을 사용하여 특정 URL 패턴과 서블릿 클래스를 매핑하면,
해당 URL로 요청이 들어올 때 애노테이션에 지정된 서블릿이 실행됩니다.
필터: 필터는 서블릿이나 리소스 요청을 가로채서 요청 전처리나 응답 후처리 작업을 수행하는 데 사용됩니다.
필터를 사용하여 애노테이션으로 수행되는 기능 이외의 작업을 추가로 처리할 수 있습니다.
EX)
애노테이션을 통한 서블릿 매핑: 애노테이션을 사용하여 특정 URL 주소와 서블릿 클래스를 연결할 수 있습니다.
해당 URL로 요청이 들어올 때 애노테이션에 지정된 서블릿이 실행됩니다.
필터를 통한 기능 추가 및 가로채기: 필터는 서블릿이나 리소스의 요청을 가로채서 요청 전처리나
응답 후처리 작업을 수행하는 데 사용됩니다.
필터를 사용하여 보안 인증, 로깅, 데이터 변환 등 특수한 기능을 추가하거나 요청을 가로챌 수 있습니다.
예를 들어,
특정 URL로 접근하려고 할 때, 필터가 해당 요청을 가로채서 사용자 인증을 확인하고,
인증되지 않은 사용자에게는 로그인 화면으로 리다이렉트하도록 설정할 수 있습니다.
또는 필터를 사용하여 요청의 파라미터를 검증하거나 요청과 응답의 데이터를 압축하여
효율적인 통신을 구현할 수 있습니다.
따라서 애노테이션과 필터를 통해 웹 애플리케이션에 보안, 로깅, 국제화와 같은 추가 기능을 쉽게 구현하거나
특정 요청을 가로채서 조작할 수 있습니다.
#예제코드 (주석 읽어보기)
# Filter
package eomcs.servlet.ex02;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
// 서블릿 컨테이너가 관리하는 컴포넌트
// => 서블릿, 필터, 리스너
//
// 필터 만들기
// => javax.servlet.Filter 인터페이스 규칙에 따라 작성한다.
//
// 필터 배포하기
// => DD 파일(web.xml)에 설정하기
// <!-- 필터 등록 -->
// <filter>
// <filter-name>f01</filter-name>
// <filter-class>com.eomcs.web.ex02.Filter01</filter-class>
// </filter>
//
// <!-- 필터를 적용할 URL 설정 -->
// <filter-mapping>
// <filter-name>f01</filter-name>
// <url-pattern>/ex02/*</url-pattern>
// </filter-mapping>
// => 애노테이션으로 설정하기
// @WebFilter(URL)
//
// 필터의 용도
// => 서블릿을 실행하기 전후에 필요한 작업을 수행
// => 서블릿 실행 전
// - 웹브라우저가 보낸 암호화된 파라미터 값을 서블릿으로 전달하기 전에 암호 해제하기
// - 웹브라우저가 보낸 압축된 데이터를 서블릿으로 전달하기 전에 압축 해제하기
// - 서블릿의 실행을 요청할 권한이 있는지 검사하기
// - 로그인 사용자인지 검사하기
// - 로그 남기기
// => 서블릿 실행 후
// - 클라이언트로 보낼 데이터를 압축하기
// - 클라이언트로 보낼 데이터를 암호화시키기
//
//@WebFilter("/ex02/*")
public class Filter01 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 웹 애플리케이션을 시작할 때 필터 객체를 생성한다.
// 이 메서드는 필터 객체를 생성한 후 자동으로 호출된다.
// 필터가 사용할 자원을 이 메서드에서 준비한다.
// => 웹 애플리케이션을 시작할 때 필터는 자동 생성된다.
System.out.println("Filter01.init()");
}
@Override
public void destroy() {
// 웹 애플리케이션을 종료할 때 호출된다.
// init()에서 준비한 자원을 해제한다.
System.out.println("Filter01.destroy()");
}
@Override
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
// 요청이 들어 올 때 마다 호출된다.
// => 단 필터를 설정할 때 지정된 URL의 요청에만 호출된다.
// => 서블릿이 실행되기 전에 필터가 먼저 실행된다.
// => 서블릿을 실행한 후 다시 필터로 리턴한다.
System.out.println("Filter01.doFilter() : 시작");
// 다음 필터를 실행한다.
// 만약 다음 필터가 없으면,
// 요청한 서블릿의 service() 메서드를 호출한다.
// service() 메서드 호출이 끝나면 리턴된다.
chain.doFilter(request, response);
// 체인에 연결된 필터나 서블릿이 모두 실행된 다음에
// 다시 이 필터로 리턴될 것이다.
System.out.println("Filter01.doFilter() : 종료");
}
}
# Listener
package eomcs.servlet.ex02;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
// 서블릿 컨테이너가 관리하는 컴포넌트
// => 서블릿, 필터, 리스너
//
// 리스너 만들기
// => 서블릿 컨테이너 또는 서블릿, 세션 등의 객체 상태가 변경되었을 때 보고 받는 옵저버
// => "Observer" 디자인 패턴이 적용된 것이다.
// => ServletContextListener
// - 서블릿 컨테이너를 시작하거나 종료할 때 보고 받고 싶다면 이 인터페이스를 구현하라.
// => ServletRequestListener
// - 요청이 들어오거나 응답할 때 보고 받고 싶다면 이 인터페이스를 구현하라.
// => HttpSessionListener
// - 세션이 생성되거나 종료될 때 보고 받고 싶다면 이 인터페이스를 구현하라.
// => XxxListener
// - 기타 다양한 인터페이스가 있다. 문서를 참고하라.
//
// 리스너 배포하기
//=> DD 파일(web.xml)에 설정하기
// <listener>
// <listener-class>com.eomcs.web.ex02.Listener01</listener-class>
// </listener>
//
//=> 애노테이션으로 설정하기
// @WebListener
//
// 리스너의 용도
// => 서블릿 컨테이너나, 세션 등이 특별한 상태일 때 필요한 작업을 수행한다.
// => ServletContextListener
// - 웹 애플리케이션을 시작할 때 Spring IoC 컨테이너 준비하기
// - 웹 애플리케이션을 시작할 때 DB 커넥션 풀 준비하기
// - 웹 애플리케이션을 종료할 때 DB 커넥션 풀에 들어 있는 모든 연결을 해제하기
// => ServletRequestListener
// - 요청이 들어 올 때 로그 남기기
//
//
//@WebListener
public class Listener01 implements ServletContextListener {
public Listener01() {
System.out.println("Listener01() 호출됨!");
}
@Override
public void contextInitialized(ServletContextEvent sce) {
// 웹 애플리케이션이 시작될 때 호출된다.
System.out.println("Listener01.contextInitialized()");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
// 웹 애플리케이션이 종료될 때 호출된다.
System.out.println("Listener01.contextDestroyed()");
}
}
# Servlet
// 필터나 리스너를 테스트하기 위한 서블릿
package eomcs.servlet.ex02;
import java.io.IOException;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
@WebServlet("/ex02/s1")
public class Servlet01 extends GenericServlet {
private static final long serialVersionUID = 1L;
@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
System.out.println("/ex02/s1 서블릿 실행!");
}
}