Filter

EUNJI LEE·2023년 6월 9일
0

Servlet/JSP

목록 보기
7/9

Filter

javax.servlet.Filter 인터페이스를 상속 받아서 구현한 클래스로 특정 패턴을 통해서 요청 정보를 서블릿에 전달할 때 사용한다. 요청을 실행하는 Servlet을 실행하기 전에 Filter를 거쳐서 실행하는 구조로 동작한다. Servlet이 따로 응답하지 않고 Filter를 통해서 요청을 처리하고 응답하는 것도 가능하다.

filter를 지정한 경우 서블릿이 실행되기 전에 filter부터 실행되기 때문에 권한이나 로그인 여부를 설정하거나 인코딩 처리를 하는 등 공공 로직에 많이 사용한다.

다수의 filter를 중복해서 사용하는 것도 가능하므로 인코딩을 실행하는 filter와 로그인 여부를 판단하는 filter를 중복 사용 가능하다.

web.xml을 이용해서 설정

web.xml 파일에서 filter의 이름과 필터를 구현한 클래스, 초기값 설정 이름, 설정값 등을 작성해서 filter를 등록할 수 있다.

<filter-name> : filter의 이름을 작성한다.

<filter-class> : filter를 구현한 클래스의 경로를 작성한다.

<filter-mapping> : 등록할 필터를 매핑한다.

<url-pattern> : 요청할 페이지 형식을 지정한다.

<servlet-name> : 적용할 서블릿 명을 작성한다.

<filter>
		<filter-name>basicfilter</filter-name>
		<filter-class>com.filtertest.common.filter.BasicFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>basicfilter</filter-name>
		<url-pattern>/*</url-pattern>
		<!-- /* : 전체 경로에 지정 -->
	</filter-mapping>

어노테이션으로 설정

@WebFilter() 안에 servletNames = {"서블릿명1","서블릿명2"} 혹은 urlpatterns={”url패턴”,”url패턴1”} 을 작성해서 사용할 수 있다.

//필터 중복 사용
@WebFilter(servletNames = {"memberManager","encoding"})
//memberManager라는 서블릿과 encoding이라는 서블릿에 적용되는 필터
public class AdminCheckFilter extends HttpFilter implements Filter {
}
------------------------------------------------------------------------------------
//필터 단일 사용
@WebFilter(servletNames = "memberView")
public class CheckAthunicate extends HttpFilter implements Filter {
}
------------------------------------------------------------------------------------
@WebFilter("/*") //단일 url패턴 작성 시 생략 가능
//프로젝트 내의 모든 서블릿에 적용되는 필터
public class EncodingFilter extends HttpFilter implements Filter {
}
------------------------------------------------------------------------------------
//url패턴과 서블릿명을 같이 사용
//url주소에 /member/가 포함되는 모든 서블릿과 서블릿 명이 login, updatePwd인 경우 적용
@WebFilter(urlPatterns = { "/member/*"}, servletNames = {"login","updatePwd"})
public class PasswordEncryptoFilter extends HttpFilter implements Filter {
}

Filter 클래스

Filter 인터페이스를 상속받는 자바 클래스를 만들어서 필터로 활용할 수 있다. 사용하는 메소드는 init(), doFilter(), destroy() 등이 있다. doFilter() 메소드만 추상 메소드로 doFilter()는 필수로 구현하되 다른 메소드는 필요 여부에 따라 생략해도 된다.

필터 사용 후 요청을 따로 넘기지 않으면 그대로 실행을 종료하기 때문에 필터의 로직이 처리 된 다음 요청, 응답에 대한 처리를 넘기기 위해서 chain을 통해 요청을 넘겨줘야 한다.

init(FilterConfig fconfig)

웹 컨테이너가 필터를 호출하는 경우 해당 메소드가 호출되면서 필터 객체를 생성하고 초기화한다. 필터 객체가 생성 및 초기화 될 때 최초에 한 번 실행하는 것으로 FilterConfig 객체를 통해 web.xml에서 설정해둔 값들을 가져올 수 있다.

doFilter()

필터가 수행될 때 실행될 메소드로 request 객체와 response 객체를 사용해서 로직을 처리한 뒤 chain을 통해서 처리한 값을 서블릿으로 전송한다. doFilter 메소드를 재정의(Overiding)해서 공통의 로직을 구현한다.

doFilter() 메소드의 매개변수

  1. ServletRequest : HttpServletRequest의 부모로 request가 제공하는 메소드를 가지고 있다.

    HttpServletRequest로 형변환이 가능하다. ServletRequest는 Session객체가 없기 때문에 HttpServletRequest객체를 이용한다.

  2. ServletResponse : HttpServletResponse의 부모로 response에서 제공하는 메소드를 가지고 있다. HttpServletResponse로 형변환 해서 사용 가능하다.

  3. FilterChain : 다른 필터 또는 연결된 서블릿을 가지고 있는 객체로 다음 필터 또는 서블릿을 호출할 때 사용한다.

💡 FilterChain?
filter는 chain처럼 서로 연결되어 있다. 연결 되어있는 필터들을 순차 별로 doFilter() 메소드를 이용해서 실행시키는 인터페이스가 바로 FilterChain이다. 마지막 필터가 실행된 후에는 service() 메소드를 실행 시켜서 서블릿의 doGet(), doPost()를 실행한다.

public class BasicFilter implements Filter{
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		System.out.println("BasicFilter 실행함");
		chain.doFilter(request, response); //요청을 넘김
	}
}

destroy()

역할이 끝난 필터는 웹 컨테이너에 의해서 destroy() 메소드를 호출하고 소멸한다. init() 메소드와 같이 필터의 생성 주기를 관리하게 되는 메소드로 실행은 알아서 되기 때문에 필요한 로직만 작성하면 필터 소멸 시 알아서 사용된다.

Wrapper

전달받은 데이터를 가공해서 반환하는 클래스로 데이터 가공을 위해서 사용하는 클래스이다. filter와 연결해서 사용 시, 필요한 시점에 따라 요청인 경우 HttpServletRequestWrapper, 응답인 경우 HttpServletResponseWrapper 클래스를 통해서 구현한다.

filter와 연결해서 자주 사용하고 동적 바인딩 효과를 위해 재정의 해서 사용한다.

public class MyRequestWrapper extends HttpServletRequestWrapper{
	//HttpServletRequest를 매개변수로 갖는 생성자를 필수로 생성해야한다.
	//반대로 HttpServletResponseWrapper일 때는 HttpServletResponse를 매개변수로 받는다.
	public MyRequestWrapper(HttpServletRequest request) {
		super(request);
	}

	//getParameter 메소드 재정의
	@Override
	public String getParameter(String name) {
		String oriData=super.getParameter(name);
		//클라이언트가 보낸 원본값 request.getParameter와 동일
		return oriData+"@test.com"; //모든 원본 데이터 뒤에 @test.com를 붙이게된다.
	}
}
profile
천천히 기록해보는 비비로그

0개의 댓글