본문 바로가기

학원/복기

[MVC] 필터(Filter)

 

필터(Filter)

 

필터는 클라이언트 요청에 대한 웹프로그램 실행 전 또는 후에 실행될 기능을 제공한다. 

필터는 WAS(웹컨테이너)에 의해 관리되며 XSS 방어, 인코딩 변환처리, 요청에 대한 인증, 권한 검사 등에 사용한다.

 

필터를 사용하기 위해서는 필터 기능을 제공해주는 필터 클래스를 선언해주어야 한다.

 

 

필터 클래스

 

필터 클래스는 클라이언트 요청에 대한 웹프로그램 실행 전 또는 후에 동작될 명령을 작성하기 위한 클래스이며 Filter 인터페이스를 상속받아 작성해야 한다.

필터 클래스는 @WebFilter 어노테이션 또는 [web.xml] 파일의 엘리먼트를 사용하여 필터 클래스를 필터로 등록하고, URL 패턴 정보를 매핑 처리해야 사용이 가능하다. (서블릿과 유사) 

 

 

예시)

 

예시로 클라이언트가 요청하는 모든 웹프로그램의 실행 전에 리퀘스트 메세지 몸체부에 저장되어 전달되는 값에 대한 캐릭터셋을 변경하는 기능을 제공하는 필터 클래스(인코딩 필터)를 작성해보자. 

 

servlet이 제공하는 Filter을 상속받아야 한다.

 

FilterChain.doFilter(ServletRequest request, ServletResponse response) 

: 다른 필터 객체를 연결하여 사용하기 위한 메소드

→ 필터 객체가 없는 서블릿과 연결되어 웹프로그램을 실행한다.

 

chain.doFilter()를 기준으로 이전에는 웹프로그램 실행 전 동작될 명령을 작성하고, 이후에는 웹프로그램 실행 후에 동작될 명령을 작성해주면 된다.

package xyz.itwill.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

//필터 클래스
public class EncodingFilter implements Filter {
	
	//웹프로그램 실행 전 또는 후에 동작될 명령을 작성하는 메소드
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		//웹프로그램 실행 전에 동작될 명령 작성
		if(request.getCharacterEncoding() == null || 
				!request.getCharacterEncoding().equalsIgnoreCase("utf-8")) {
			request.setCharacterEncoding("utf-8");
		}
		
		chain.doFilter(request, response);//다른 필터 객체를 연결하여 사용
		
		
		//웹프로그램 실행 후에 동작될 명령 작성
		
	}

}

 

 

[web.xml] 에서 filter 엘리먼트를 이용해 필터를 등록해주자.

 

filter : 클래스를 필터(Filter)로 등록하기 위한 엘리먼트 → servlet 엘리먼트 선언 전에 작성하는 것을 권장한다.

filter-mapping : 필터가 실행되기 위한 요청 웹프로그램의 URL 패턴을 등록하기 위한 엘리먼트 

  <filter>
  	<filter-name>encoding filter</filter-name>
  <filter-class>xyz.itwill.filter.EncodingFilter</filter-class>
  </filter>
  
  <filter-mapping>
  	<filter-name>encoding filter</filter-name>
  	<!-- 클라이언트가 모든 웹프로그램을 요청한 경우 필터 동작되도록 URL 등록 -->
  	<url-pattern>/*</url-pattern>
  </filter-mapping>

 

이처럼 인코딩 필터를 사용하면 전달된 값에 대한 캐릭터셋이 모두 자동으로 utf-8로 변경되어 전달되어 작업이 편리해진다.

request.setCharacterEncoding()을 사용할 필요 X

 


 

이를 조금 더 유지보수가 쉽게 작성해보자.

 

[web.xml]의 filter 엘리먼트에 init-param 엘리먼트를 추가한다.

init-param : 서블릿 클래스에 필요한 값을 제공하기 위한 엘리먼트

 <filter>
  	<filter-name>encoding filter</filter-name>
  	<filter-class>xyz.itwill.filter.EncodingFilter</filter-class>
  	<init-param>
  		<param-name>encoding</param-name>
  		<param-value>utf-8</param-value>
  	</init-param>
  </filter>

 

 

EncodingFilter 클래스로 돌아가서 init 메소드를 오버라이드 해준다.

	//필터를 동작하기 위한 필터 클래스를 객체로 생성한 후 가장 먼저 한번만 호출되는 메소드
	// => 초기화 작업에 필요한 명령 작성
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		//코드 작성
        //...
	}

 

FilterConfig.getinitParameter(String name) : [web.xml] 파일에서 init-param 엘리먼트로 제공되는 값을 얻어와 반환하는 메소드

 

[EncodingFilter.java]

package xyz.itwill.filter;

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;

//필터 클래스
public class EncodingFilter implements Filter {
	private String encoding;
	
	//필터를 동작하기 위한 필터 클래스를 객체로 생성한 후 가장 먼저 한번만 호출되는 메소드
	// => 초기화 작업에 필요한 명령 작성
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		encoding=filterConfig.getInitParameter("encoding");
	}
	
	
	//웹프로그램 실행 전 또는 후에 동작될 명령을 작성하는 메소드
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		//웹프로그램 실행 전에 동작될 명령 작성
		if(request.getCharacterEncoding() == null || 
				!request.getCharacterEncoding().equalsIgnoreCase("utf-8")) {
			request.setCharacterEncoding(encoding);//utf-8 대신 encoding 사용 
		}
		
		chain.doFilter(request, response);//다른 필터 객체를 연결하여 사용
	}
}

 

이렇게 하면 유지보수에 더 효율적이다.