01. 필터란 무엇인가 ?
HTTP 요청과 응듭을 변경할수 있는 재 사용가능한 코드 이다. 필터는 객체의 형태로 존재하며 클라이언트로 부터 오는 요청과 최정자원 사이에 위치하여 클라이언트의 요청 정보를 알맞게 변경할수 있으며, 또한 필터는 최종 자원과 클라이언트 가능 응답 사이에 위치하여 최종자원의 요청결과를 알맞게 변경할수 있다.
자원이 받게 되는 요청 정보는 클라이언트와 자원 사이에 존재하는 필어에 의해 변경된 요청 정보가 되며, 도한 클라이언트가 보게 되는 응답 정보는 클라이언트와 자원사이에 존재하는 필터에 의해 변경된 응답 정보가 된다.
클라이언트와 자원사이에 한개의 필터만 존재할수 있는 것은 아니며, 여러개의 필터가 모여 하나의 필터 체인을 형성하게 된다.
여러개의 필터가 모여서 하나의 체인을 형성할떄 첫번째 필터가 변경하는 요청 정보는 클라이언트의 요청 정보가 되지만, 체인의 두번째 필터가 변경하는 요청정보는 첫번째 필터를 통해 변경된 요청정보가 된다. 즉, 요청 정보는 변경에 변경을 거듭하게 되는 것이다.
02. 필터의 구현
2.1 필터 인터페이스
Fileter 인터페이스는 다음과 같은 메서드를 선언하고 있으며, 필터 기능을 제공할 클래스느 ㄴ필터 인터페이스를 알맞게 구현해 주어야 한다.
public void init(FilterConfig filterConfig) throwxception : 필터를 초기화 할때 호출 된다.
public void doFilter(ServletRequest request, ServletResponse response, Filter Chain chain) throws java.io.IOException, ServletException : 체인을 따라 다음에 존재하는 필터로 이동한다. 체인의 가장 마지막에는 클라이언트가 요청한 최종 자원이 위차한다.
public void destory() : 필터가 웹 컨테이너에서 삭제될 때 호출된다.
public class FilrstFilter implements Filter{
public void init(FiltercONfig filterConfig) throws ServletException{
//필터 초기화 작업
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain Chain) throws IOException, SevletExceptiion{
//1. request 파ㄹ미터를 이용하여 오청의 필터 작업 수행
//2. 체인의 다음 필터 처리
chain.doFilter(request, response)
//3. response를 이용하여 응답의 필터링 작업 수행
}
public void destory(){
//주로 필터가 사용한 자원을 반납
}
}
위 코드에서 filter 인터페이스의 doFilter()메소드는 요청이 있을때 마나 매번 실행된다. 예를들어, 클라이언트가 요청한 자원이 필터를 거치는 경우 클라이언트의 요청이 있을때마나 doFilter()메서드가 호출되며, doFilter() 메소드는 JSP/서블릿과 마찬가지로 요청에 대해서 알맞은 작업을 처리하게 된다.
1. request 파라미터를 이용하여 클라이언트의 요청 필터링 : 1단계에서는 RequestWWrapper클래스를 사용하여 클라이언트의 요청을 변경한다.
2. chain.doFilte() apthem ghcnf : 2단계에서는 요청의 필터링 결과를 다음 필터에 전달한다.
3. response 파라미터를 사용하여 클라이언트로 가능 응답필터링 : 3단계에서는 체인을 통해서 전달되 ㄴ응답데이터를 변경하여 그 결과를 클라이언트에 전송한다.
2.2 필터 설정하기
필터를 사용하기 위해서는 어떤 필터가 어떤 자원에 대해서 적도용된다는 것을 웹 컨테이너에 알려주어야 한다. 지금까지 웹 어플리케이션과 관련된 설정 정보를 web.xml 파일에 명시했듯이 필터에 관한 정보도 web.xml 파일을 통해서 설정하게 되어있다.
<filter>
<filter-name>FilterName</filter-name>
<filter-class>javacan.filter.FileClass</filter-class>
<init-param>
<param-name>paramName</param-name>
</init-param>
</filter>
<filter-mapping>
<filter-name>FilterName<filter-name>
<url-pattern>*.jsp</url-pattern>
<//filter-mapping>
<filter>태그는 웹 어플리케이션에서 사용될 필터를 지정하는 역할이며, <filter-mapping> 태그는 특정 자원에 대해 어떤 필터를 사용할지 지정한다.
<init-param>태그는 필터가 초기화될떄, 즉 필터의 init() 메소드가 호출될때 전달되는 파라미터값이다. 이는 서블릿의 초기화 파라미터와 비슷한 역할을 하며, 주로 필터를 사용하기전에 초기화 해야 하는 객체나 자원을 할당할때 필요한 정보를 제공하기 위해 사용된다.
<url-pattern> 태그는 클라리언트가 요청한 특정 URI에 대해서 필터링할때 사용된다.
필터 매핑정보
<filter-mapping>
<filter-name>AuthCheckFilter</filter-name>
<url-pattern>/pds/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>IPCheckFilter</filter-name>
<url-pattern>/pds/data/*</url-pattern>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
ㅇ웹 브라우저 /pds/data/download.jsp를 요청헀다고 해보자. 이경우 두개의 필터 매핑 모두 <url-pattern>에 따라서 이 URL을 처리할수 있게 된다. 그런데 두번째 필터 매핑은<dispatcher>의 값이 INCLUDE 이기 떄문에 웹 브라우저의 요청에 대해서는 필터가 적용되지 않는다.
<jsp:include page=”/pds/data/util.jsp” flush=”false”/>
2.3 요청 및 응답 래퍼 클래스
필터가 필터로서의 젝 기능을 하기 위해서는 클라이언트의 요청을변경하고, 또한 클라이언트로 가는 응답을 변경할수 있어야 할 것이다. 이러한 변경을 할수 있도록 해주는 것이 바로 servletRequsetWrapper와 ServletResponseWrapper이다. 서블릿 요청/응답 래퍼클래스를 이용함으로써 클라이언트의 요청 정보를 변경하여 최종자원인 서블릿 /기타자원에 전달할수 있고 또한 최종 자원으로부터의 응답결과를 변경하여 새로운 응답 정보를 클라이언트에 보낼수 있게 된다.
03 필터의 응용
필터를 사용하는 방버에는 제한이 없으며, 얼마나 필터의 특징을 잘 활용하느냐에 따라서 필터의 응용범위가 달라질수 있다. 서블릿 규약에서는 다음과 같은 응용 분야를 제시하고 있다.
ㅇ 데이터변환
ㅇ xsl/t를 이용한 xml문서 변경
ㅇ 사용자 인증
ㅇ 캐싱 필터
ㅇ 자원 접근에 대한 로깅