2011년 3월 29일 화요일

Filter에서 Spring DI 사용하기

필터는 일반적으로 서블릿 컨테이너에서 제어하기 때문에 스프링 어플리케이션에서 관리하는 빈을 DI 받을 수 없다.

아래의 필터 클래스를 살펴보자.



package com.archnal.securityweb.web;

import java.io.IOException;

import javax.annotation.Resource;
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.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

// import 생략

@Service("restfulAuthFilter")
public class RestfulAuthFilter implements Filter {
  
  @Resource(name="statusMessageBuilder")
  StatusMessageBuilder messageBuilder;

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

  @Override
  public void doFilter(ServletRequest request, ServletResponse response,
      FilterChain filterChain) throws IOException, ServletException {
    
    .. 생략

    String message = messageBuilder.getErrorMessage("AUTH_ERROR");

    
    filterChain.doFilter(request, response);
    
  }

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

  
}


doFilter 메서드 안에서 DI 된 messageBuilder를 사용하고 있다.

스프링 DI를 사용하지 않는 일반 필터처럼 web.xml 파일에 아래와 같이 지정하면 messageBuilder.getErrorMessage("AUTH_ERROR")를 실행할 때 NullPointerException 이 발생한다.
스프링 어플리케이션 컨텍스트에 의해서 DI가 실행되지 않았기 때문에 여전히 messageBuilder가 null이기 때문이다.


  <filter>
    <filter-name>restfulAuthFilter</filter-name>
    <filter-class>
      com.archnal.securityweb.web.RestfulAuthFilter
    </filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>utf-8</param-value>
    </init-param>
  </filter>
  
  <filter-mapping>
    <filter-name>restfulAuthFilter</filter-name>
    <url-pattern>/ws/rest/secure/*</url-pattern>
  </filter-mapping>
  

이런 경우 스프링컨텍스트의 DI를 이용해서 필터를 구현하고자 하는 경우에는 아래와 같이 web.xml 파일을 설정해야 한다.

  <filter>
    <filter-name>restfulAuthFilter</filter-name>
    
    <filter-class>
      org.springframework.web.filter.DelegatingFilterProxy
    </filter-class>

    <init-param>
      <param-name>encoding</param-name>
      <param-value>utf-8</param-value>
    </init-param>
  </filter>
  
  <filter-mapping>
    <filter-name>restfulAuthFilter</filter-name>
    <url-pattern>/ws/rest/secure/*</url-pattern>
  </filter-mapping>  


주의해야 할 점은 filter-name과 필터 클래스의 빈 이름이 동일해야 한다.

위의 필터의 타입레벨 annotation으로 @Service("restfulAuthFilter") 설정된 restfulAuthFilter가 filter-name으로 사용되어야 한다.

위와 같이 web.xml 파일을 설정하면 스프링의 DI를 이용하여 필터를 작성할 수 있다.

댓글 없음:

댓글 쓰기