JSP & Servlet

Filter.1

Jungsoomin :) 2020. 7. 17. 09:58

 스프링 프레임워크 시동시 CharaterEncodingFilter 등 filter들을 web.xml에 정의해두는 일을 보면서 의아해한적이있다.

 

<fiter>태그에는 <fliter-name> 으로 필터의 별칭을, <filter-class>필터 클래스를 명시한다. 구현필터는 Filter를 구현하고 있다.

 Servlet과 Filter를 매핑 하려면 <filter-mapping>태그 안에 <servlet-name>을 주면되며,  url로 매핑하고 싶다면 <url-pattern>을 주면된다. 하나 필터에 다수의 서블릿  이름도 줄 수 있다.

 

   <dispatcher>태그를 주면 경우에 따라 필터를 적용시킨다.

  • REQUEST 클라이언트의 요청인 경우 필터적용(기본값)

  • FORWARD forward()를 통해서 제어흐름을 이동하는 경우 적용

  • INCLUDE includ() 를통해서 포함되는 경우 적용

<servlet>
  	<servlet-name>ServletEx1</servlet-name>
  		<servlet-class>chap19.ServletEx1</servlet-class>
  	</servlet>
  	
  	<servlet-mapping>
  		<servlet-name>ServletEx1</servlet-name>
  		<url-pattern>/ServletEx1</url-pattern>
  	</servlet-mapping>
  	
  	<filter>
  		<filter-name>Filter1</filter-name>
  		<filter-class>chap19.FilterEx1</filter-class>
  	</filter>
  	
  	<filter>
  		<filter-name>Filter2</filter-name><!-- xml로 정해놓은 필터도 xml로 맵핑해야한다. -->
  		<filter-class>chap19.FilterEx2</filter-class>
  	</filter>
  	
  	<!-- 필터는 web.xml에 filter-mapping으로 정의된순서대로 작동한다. -->
  	
  	
  	<filter-mapping>
  		<filter-name>Filter1</filter-name> <!-- 필터와 서블릿을 엮기위해서는 filter-mapping에 serlvet-name을 추가한다. -->
  		<servlet-name>ServletEx1</servlet-name>
  	</filter-mapping>
  
  	<filter-mapping>
  		<filter-name>Filter2</filter-name>
  		<servlet-name>ServletEx1</servlet-name>
  	</filter-mapping>

Filter 인터페이스 구현 객체의 재정의 메서드에는 init() , destroy() , doFilter() 가 있는데,

    doFilter가 가장중요한 메서드이고, init()나 destroy()는 springContainer의 관리에 따라 움직이기 때문에 재정의 해도 효과를 받지 못한다고 기억한다.

public class ServletEx1 extends HttpServlet {
	private static final long serialVersionUID = 1L;
       

    public ServletEx1() {
        super();
        // TODO Auto-generated constructor stub
    }


	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("서블릿1작동");
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}


	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

 


doFilter의 매개변수를 보면 ServletReponse , SerlvetRequest , FilterChain 으로 되어있는데 HTTP 프로토콜을 사용하므로 

이를 HttpServletResponse , HttpServletRequest 로 변환해 주어야한다. 

  • FilterChain은 각 필터를 거쳐 서블릿까지 가는 목록을 가지고 있는데, 다음 필터로 넘어가거나 필터를 거쳐 마지막 서블릿까지 가는데에 사용하는 메서드가 FilterChain의 .doFilter 메서드이다. 

  • 이를 조작하면 필터흐름과 종료지점을 정의할 수 있고 web.xml의

  •  

  • <filter-mapping>태그의 순서필터의 실행순서 또한 정의 할 수 있다.

  • <filter-mapping>태그안에 <url-pattern> <servlet-name>이 섞여 있을경우, url 패턴순으로 정렬하고나서 servlet-name 순으로 정렬시킨다.

 

public class FilterEx1 implements Filter {


    public FilterEx1() {
        // TODO Auto-generated constructor stub
    }


	public void destroy() {
		// TODO Auto-generated method stub
	}

//chain은 필터목록을 가지고 있다. 다음 필터가 해야하는 일은 chain의 do.Filter메소드로 실행한다.
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//		Http프로토콜이 아닌 서블릿요청 응답이므로 캐스팅을 해야한다.		
		System.out.println("필터 1 통과");

		// pass the request along the filter chain
		chain.doFilter(request, response);
		//마지막 chain의 doFilter 메소드는 Servlet 을 작동시킨다.
	}


	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

}

@WebFilter 에노테이션으로 필터를 정의할 수 있지만, 순서는 보장되지 않으므로, 순번이 관계 없을때 사용하는것이 바람직하다.

 속성으로는

  1. urlPatterns {필터적용 URL 패턴목록}

  2. servletNames:적용할 서블릿 이름 목록
  3. filterName: 필터이름
  4. initParam: 초기화 파라미터목록지정
  5. dipatcherType:필터의 적용범위, DispatcherType의 열거상수로 지정한다.