[Spring]스프링 레거시 - 초기 설정(2)

Inung_92·2023년 2월 18일
2

Spring

목록 보기
8/15
post-thumbnail

필터란?

📖 요청 발생 시 DispatcherServlet보다 먼저 요청을 접수하여 요청에 대한 부가작업 또는 정제하는 역할을 수행할 수 있는 객체

DispatcherServlet(이하 디스패쳐)은 스프링 컨텍스트 내에 포함되어 있지만 필터는 톰캣과 같은 웹 컨텍스트에서 관리하는 객체이다. 따라서 스프링에서만 사용할 수 있는 객체가 아니라는 의미이기도하다.

⚡️ 필터의 역할

필터는 디스패쳐 서블릿이 요청을 접수하기 전에 먼저 요청 처리에 필요한 초기 설정들을 적용하거나 기타 부가작업을 할 수 있는 역할을 수행한다. 예를 들어 요청을 처리할 때마다 반복적으로 수행하는 동작이 있다면 필터를 설정하여 해결할 수 있다. 즉, 필터는 반복적이거나 선행되어야하는 기능을 사전에 수행하여 코드를 간소화하고 유지보수성을 높이는 역할을 한다.

스프링 컨텍스트에도 이와 비슷한 역할을 하는 객체는 Interceptor(이하 인터셉터)이다. 역할은 비슷하지만 호출되는 시점이 다르다는 것이 가장 큰 차이점이다. 필터는 웹 컨텍스트의 범위 내에서 관리되어 스프링 컨텍스트 진입 이전에 호출되지만 인터셉터는 디스패쳐 서블릿이 컨트롤러에 접근하는 사이에 호출된다.
인터셉터에 대한 자세한 설명은 따로 다루도록 하겠다.

⚡️ 필터의 메소드

  • init(): 필터 객체가 생성되고 1회만 실행되며 초기화 설정을 담당
  • doFilet(): Http 요청이 Spring Context로 전달되기 전에 Web Context에 의해 실행되는 메소드로 FilterChain 객체를 통해 다음 대상으로 요청과 응답 객체를 전달
  • destroy(): 필터의 역할이 종료되어 자원을 반납할 때 사용되는 메소드

init() 메소드로 필터를 1회 초기화하면 이후 모든 요청은 doFilter()메소드가 처리하며, destroy() 메소드를 실행한 후에는 더 이상 doFilter() 메소드에 의해 요청이 처리되지 않는다.

//Filter를 직접 정의하려면 Filter 인터페이스를 구현하여야함.
public interface Filter {
 	
    //필터 초기화
    public default void init(FilterConfig filterConfig) throws ServletException {}
 	
    //초기화 이후 모든 요청 처리
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException;
 	
    //요청 처리가 완료되면 자원 반납
    public default void destroy() {}

필터 사용

⚡️ 필터 등록 방법

필터를 bean으로 등록하기 위해서는 2가지 방법을 사용할 수 있다.

  • .java를 이용하여 @bean 어노테이션으로 생성
  • web.xml에 직접 bean으로 등록

위 두가지 방법에 대해서 알아보자.

🖥️ FilterRegistrationBean 이용(.java)

@Configuration
public class Config{
	
    @Bean  //어노테이션 설정
    public FilterRegistrationBean firstFilterRegist(){
    	//Filter interface를 구현한 FirstFilter 생성자 파라미터로 전달
    	FilterRegistrationBean registrationBean = new FilterRegistrationBean(new FirstFilter());
    	return registrationBean;
    }
}

이렇게 해주면 스프링 빈 컨테이너에 의해서 필터를 사용할 수 있게 됩니다. 다음은 xml을 이용해서 설정하는 방법을 알아보겠다.

🖥️ web.xml

xml에 직접 bean을 등록해주는 경우 디스패쳐 서블릿이 등록되기 전에 등록이 되어있어야 하므로 해당 태그 상단에 작성해주자.

<!-- 필터 적용 -->
<filter>
  <!-- 사용용도에 적합한 이름부여 -->
  <filter-name>encodingFilter</filter-name>
  <!-- 웹 컨텍스트에서 관리하는 객체를 구현한 스프링 필터를 지정 -->
  <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  <init-param> <!--init() 메서드에서 전달받을 파라미터 설정-->
    <param-name>encoding</param-name> <!--스프링에서 파라미터명 고정-->
    <param-value>UTF-8</param-value>
  </init-param>
</filter>

<!-- 매핑정보 등록 -->
<filter-mapping>
  <filter-name>encodingFilter</filter-name>
  <url-pattern>/*</url-pattern> <!-- 루트 url내 모든 요청에 적용 -->
</filter-mapping>

예시에서 처럼 인코딩처리에 대한 필터를 등록하면 일일이 요청이 들어올때마다 인코딩 설정을 해주지 않아도 필터가 자동으로 처리를 해준다.

request.setCharacterSet();

위 메소드를 더 이상 반복적으로 호출하지 않아도 된다는 뜻이다.

⚡️ 필터 사용 예시

이번엔 직접 필터 객체를 정의하고 필터 인터페이스로부터 구현을 강제 받은 3개의 메소드를 사용하는 예시를 확인해보자.

🖥️ CharacterEncodingFilter.java

//interface 구현
public class CharacterEncodingFilter implements Filter {
	//xml에 등록한 init-param을 받을 변수
    private String encoding;
	
    //초기화 메소드
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
    	/*
        -filterConfig 객체로부터 init-param 값 획득
        -여기서 init-param의 키 값은 xml에 등록한 param-name
        */
		encoding = filterConfig.getInitParameter("encoding");
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
        //요청객체 인코딩 설정
		request.setCharacterEncoding(encoding);
        //FilterChain 객체를 통해 요청 및 응답 객체 다음 대상으로 전달
		chain.doFilter(request, response);
	}

	@Override
	public void destroy() {
		//필터 소멸 전 처리해야할 코드 작성
	}
}

이렇게 작성해주면 필터는 디스패쳐 서블릿이 요청을 접수하기 전에 초기화 및 일부 로직을 수행하고 해당 요청 및 응답 객체를 디스패쳐 서블릿으로 전달하는 역할한다.


마무리

이번 게시글에서는 필터에 대해서 알아보았다. 간략하게 정리해보자.

  • 필터는 웹 컨텍스트가 관리
  • 필터는 디스패쳐 서블릿이 요청을 접수하기 전에 부가적인 기능 및 설정을 담당
  • 필터는 다양한 기능(접근권한 확인, 인코딩 설정 등)을 본격적인 요청 처리 이전에 수행 가능
  • 필터를 사용하여 코드 간소화 및 유지보수성 향상 가능

아직 필터를 많이 사용해보지는 않았기 때문에 정확히 어떤 부분에서 어떻게 활용되는지에 대한 경험은 부족하다. 하지만 필터의 역할과 메소드들의 방식을 차근차근 생각하면서 과연 요청을 처리하기 이전에 어떤 부분을 처리해주면 좋을지 생각해본다면 훨씬 활용도가 높고, 업무처리의 효율성의 높아질 것이라고 생각된다.

그럼 이만.👊🏽

profile
서핑하는 개발자🏄🏽

0개의 댓글