JSP (JavaServer Pages)에서 필터(Filter)는 웹 애플리케이션의 요청과 응답을 처리하는 중요한 구성 요소이다.
모든 자바 클래스는 POJO인데 대표적인 not POJO 가 서블릿이다.
그 중 서블릿을 상속받은 Filter에 대해 알아보자.
필터는 요청과 응답을 가로채어 서블릿과 JSP 페이지가 처리되기 전에 보안 관련 작업을 수행하는 데 유용하다.
보통 사용자 인증이나 권한이 있는지 체크할 때 사용된다.
예시로는, 네이버 웹툰 사이트에서 쿠키로 구매해야지 볼 수 있는 웹툰의 사이트를 권한이 없는데(== 쿠키로 구매하지 않았는데) 그 사이트 url을 알고 접속을 시도하는 경우가 그렇다.
네이버 웹툰의 경우, 접속을 시도하면, 해당 웹툰의 목록페이지로 이동하도록 로직이 짜여있다.
필터를 사용하기 위해서는 web.xml 파일이나 어노테이션(@)을 사용하여 필터를 등록해야 한다.
- web.xml을 사용하는 경우
<filter>
<display-name>ValidFilter</display-name>
<filter-name>ValidFilter</filter-name>
<filter-class>controller.common.ValidFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ValidFilter</filter-name>
<url-pattern>/ValidFilter</url-pattern>
</filter-mapping>
위 코드는 필터를 등록하는 web.xml의 일부이다.
- 어노테이션을 사용하는 경우
@WebFilter("*.do")
위 코드를 Filter 파일에 작성하면 된다.
다음은 필터 요청 처리의 흐름에 대해 알아보자.
요청 수신: 클라이언트가 웹 애플리케이션에 요청을 보낸다. 이 요청은 필터 체인(filter chain)을 통해 서블릿이나 JSP 페이지로 전달된다.
↓
필터 체인 실행: 요청이 들어오면, 필터 체인에 등록된 필터들이 순서대로 호출된다. 필터 체인은 필터가 등록된 순서에 따라 실행된다.
↓
필터의 doFilter 메서드 호출: 각 필터는 doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 메서드를 구현한다. 이 메서드에서 필터는 요청을 처리하고, 다음 필터나 서블릿으로 요청을 전달하기 위해 chain.doFilter(request, response)를 호출한다.
↓
다음 필터 또는 서블릿 호출: chain.doFilter(request, response) 호출 시, 현재 필터는 요청을 다음 필터로 전달한다. 필터 체인의 마지막에 도달하면 서블릿이나 JSP가 요청을 처리한다.
↓
응답 처리: 서블릿이나 JSP가 응답을 생성하면, 이 응답은 필터 체인을 역순으로 통과하면서 각 필터가 응답을 추가적으로 처리하거나 수정할 수 있다.
위 설명을 MVC 패턴으로 쉽게 설명하면, 아래와 같다.
필터의 호출 원리
V -- |필터| logout.do-->> --|필터| main.do-->> V
필터를 사용한 예시 코드를 작성해보았다.
package controller.common;
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;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpFilter;
import jakarta.servlet.http.HttpServletRequest;
//*.do URL 패턴에 매핑된 요청에 대해 이 필터가 적용됨
@WebFilter("*.do")
public class ValidFilter extends HttpFilter implements Filter {
public ValidFilter() {
super();
}
// 필터가 종료될 때 호출되는 메서드
public void destroy() {
// 필터 종료 시 필요한 자원 정리 작업을 수행하는 코드 작성
}
// 요청과 응답을 처리하는 메서드
// 필터 체인 내에서 다음 필터를 호출함
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("로그 : 필터가 호출됨");
// 권한확인 로직
// ServletRequest를 HttpServletRequest로 형변환하여 HTTP 요청의 세부 정보에 접근
HttpServletRequest HttpRequest = (HttpServletRequest)request;
// 요청 uri 가져오기
String uri=HttpRequest.getRequestURI();
// 경로 가져오기
String cp=HttpRequest.getContextPath();
String command=uri.substring(cp.length());
// .do 로그 확인용
System.out.println("command : "+command);
// 명령어가 "/mypagePage.do"이고 세션에 로그인 정보가 없으면 예외를 발생시킴
if(command.equals("/mypagePage.do")) { // 사용자가 /mypagePage.do 요청을 했다면
if(HttpRequest.getSession().getAttribute("loginInfo") == null) { // 로그인을 안 했다면
throw new NullPointerException(); // 예외 발생시키기
}
}
/*
if(사용자가 /mypagePage.do 요청을 했니?) {
if(로그인'안'했니?) {
에러페이지로 보내버리기
}
}
*/
chain.doFilter(request, response); // 다음 필터를 호출하는 역할
}
// 필터 초기화 메서드
public void init(FilterConfig fConfig) throws ServletException { // 선언
// 초기화 시 필요한 설정 작업 수행하는 코드 작성됨
}
}
역시 not POJO답게 import가 굉장히 많이 입력되어있다.
위 코드같은 경우에는, 마이페이지는 로그인을 해야 들어갈 수 있는 페이지인데, 권한없이(로그인을 하지도 않고) 이동을 한다면, 예외를 발생시켜버리는 코드이다.
web.xml이 아닌 어노테이션을 사용하였다.
필터의 호출원리에 대한 추가 설명으로,,

command가 실행되기 전에 필터가 호출된다.
'JSP' 카테고리의 다른 글
[JSP] MVC, alert() (1) | 2024.09.04 |
---|---|
[서블릿/JSP] 리스너 (4) | 2024.09.02 |
HTTP 응답코드, 에러페이지 xml 코드 (0) | 2024.08.19 |
[JSP] JSTL, EL, 커스텀 태그에 대해서 (0) | 2024.08.16 |
[JSP] 요청방식, 응답방식 (0) | 2024.08.12 |