1. javax.servlet.filter 인터페이스를 구현한다.
init(FilterConfig)
필터 객체가 생성될 때 호출되는 메소드이다. 필처 객체는 웹 애플리케이션 서비스가 올라가면서, 즉 웹서버가 시작될 때 한번만 되어 생성되어 한번만 호출되며, init( )메소드에는 주로 초기화 기능을 구현한다.
doFilter(ServletRequest request, ServletResponse response)
doFilter( ) 메소드는 필터링 설정한 서블릿을 실행할 때마다 호출되는 메소드로서 실제 필터링 기능을 구현하는 메소드 입니다.
destory( )
필터 객체가 삭제 될 때 호출되는 메소드입니다. 따라서 destory( ) 메소드에는 주로 자원 해제 기능을 구현합니다.
아래에 두개의 필터 구현 클래스를 작성하자.
FlowFilterOne.java
package job.study.web; 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; import javax.servlet.annotation.WebFilter; /** * Servlet Filter implementation class FlowFilterOne */ public class FlowFilterOne implements Filter { String charset; /** * Default constructor. */ public FlowFilterOne() { // TODO Auto-generated constructor stub } /** * @see Filter#init(FilterConfig) */ public void init(FilterConfig fConfig) throws ServletException { // TODO Auto-generated method stub charset = fConfig.getInitParameter("en"); System.out.println("init() 호출 ......... one"); } /** * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // TODO Auto-generated method stub // place your code here System.out.println("doFilter() 호출 전 ......... one"); // pass the request along the filter chain chain.doFilter(request, response); System.out.println("doFilter() 호출 후 ......... one"); } /** * @see Filter#destroy() */ public void destroy() { // TODO Auto-generated method stub System.out.println("destory () 호출 ......... one"); } }
FlowFilterTwo.java
package job.study.web; 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; import javax.servlet.annotation.WebFilter; /** * Servlet Filter implementation class FlowFilterTwo */ public class FlowFilterTwo implements Filter { /** * Default constructor. */ public FlowFilterTwo() { // TODO Auto-generated constructor stub } /** * @see Filter#init(FilterConfig) */ public void init(FilterConfig fConfig) throws ServletException { // TODO Auto-generated method stub System.out.println("init() 호출 ......... two"); } /** * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // TODO Auto-generated method stub // place your code here System.out.println("doFilter() 호출 전 ......... two"); // pass the request along the filter chain chain.doFilter(request, response); System.out.println("doFilter() 호출 후 ......... two"); } /** * @see Filter#destroy() */ public void destroy() { // TODO Auto-generated method stub System.out.println("destory () 호출 ......... two"); } }
필터 기능을 테스트할 서블릿을 작성한다.
package job.study.web; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class SecondServlet */ @WebServlet("/second") public class SecondServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public SecondServlet() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub System.out.println("SecondServlet!!"); PrintWriter out = response.getWriter(); out.println("<html><head><title>Test</title></head>"); out.println("<body><h1>have a nice day!!</h1></body>"); out.println("</html>"); out.close(); } }
2. 필터등록
필터를 등록하는 방법은 두 가지가 있다.
주의할 점은 필터를 등록할 때는 한가지 방법으로 선택하여 등록해야 하며, 두 방법 모두를 이용해 필터를 중복하여 등록해서는 안된다. 여기서는 flow1 필터는 web.xml을 flow2 필터는 애노테이션을 이용하여 등록해보자.
- web.xml
<filter> <filter-name>flow1</filter-name> <filter-class>job.study.web.FlowFilterOne</filter-class> </filter>
- 애노테이션
@WebFilter( filterName="flow2" ) public class FlowFilterTwo implements Filter { .... 생략 .... }
애노테이션을 이용할때 한가지 알아 두어야 할게 있다.
애노테이션만으로는 필터의 실행순서를 정할 수 없다. 만약 순서를 정하고 싶다면 아래에서 링크처의 설명처럼 web.xml에 정의하고자 하는 실행순서에 따라 필터 맵핑을 순서대로 작성해주면 된다.
"WAR에서 어노테이션을 사용하여 서블릿 필터 실행 순서를 정의하는 방법"
https://lottogame.tistory.com/3712
필터맵핑
<filter-mapping> <filter-name>flow1</filter-name> <url-pattern>/second</url-pattern> </filter-mapping> <filter-mapping> <filter-name>flow2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
여러개의 필터가 등록되어 있을 때 실행되는 순서는 필터 맵핑 순으로 실행됩니다.
실행하기
웹브라우저에서 /second를 실행하고 콘솔창을 확인합니다.
필터는
- 클라이언트로부터 요청이 들어오면 /second 로 매핑된 flow1 필터의 doFilter가실행됩니다.
- 그 다음 /*으로 설정하여 모든 웹 애플리케이션 요청에 대해 매핑된 flow2 필터의 doFilter가 실행됩니다.
- web.xml에 더 이상 만족하는 조건의 필터맵핑이 없으면, 클라이언트가 요청한 서블릿이 실행됩니다.
p255, [그림 7-7]
만약, 마지막으로 수행하는 필터에서 더 이상 필터체인의 doFilter( ) 메소드를 호출하지 않으면 아래의 실행결과 처럼 서블릿의 service( ) 메소드를 실행하지 못하고 다음처럼 클라이언트에게 응답 처리가 됩니다.
ㄱ
p259, [그림7-8]