본문 바로가기
Java | Spring/Spring 입문

Spring Filter 설정

by 동기 2021. 5. 24.
반응형
  • 프로그램을 만들거나 작업을 할 때 공통되는 부분이 많아진다. 

인증 처리, 보안 처리, 로깅 처리, 페이지 인코딩 프로그램 내에서 자주 사용되는 기능을 소스 여러 군데에 사용되고 있으면 소스 양도 늘어날 것이고, 프로젝트 단위가 커질수록 서버에 대한 부하유지보수에 어려움을 겪을 수 있다. 

따라서 공통되는 부분은 빼서 관리하는게 좋다. 

공통되는 기능을 처리해주는 기능을 Spring이 제공한다. 

 

 

Filter 

  • dispatcherServlet으로 요청이 가기전에 정보 처리  

Interceptor 

  • DispatcherServlet에서 Controller(Handler) 로 가기전에 정보 처리 

 

 

  • 공통점 

Filter도 Interceptor도 모두 요청에 대한 전후 처리라고 하는 역할을 수행한다. 또한 uri기반으로 언제 실행할 것인지를 조정 가능하며, 직접 request의 내용을 파악해서 원하는 조건에 부합할 때 로직을 수행할 수 있다. 

 

 

  • 차이점 

Filter와 Interceptor는 실행되는 시점이 다르다. 

Filter는 Web Application에 등록을 하고, Interceptor는 Spring의 Context에 등록을 한다. 

 

 

 

인코딩이나 보안 관련 처리와 같은 web app의 전역적으로 처리해야 하는 로직은 Filter로 구현하고 클라이언트에서 들어오는 디테일한 처리(인증, 권한 등)에 대해서는 주로 InterCeptor로 구현한다. 

 

  • 또한 Interceptor는 Handler를 실행하기전(preHandle), Handler를 실행한 후(postHandle), view를 렌더링한 후(afterCompletion) 등, Servlet내에서도 메서드에 따라 실행 시점을 다르게 가져간다. 

 

실행 시점이 다르기 때문에 가장 큰 영향을 받는 것은 바로 예외 처리(Exception Handling)다. 

 

 

Filter에서 예외가 발생하면 Web Application에서 처리해야 한다. 

Interceptor에서 예외가 발생하면, 실행 시점이 Spring의 ServletDispatcher 내에 있기 때문에 @ControllerAdvice에서 @ExceptionHandler를 사용해서 예외를 처리를 할 수 있다. 따라서 작성 해야 할 전후처리 로직에서 예외를 전역적으로 처리하고 싶다면 Interceptor  사용하자. 

 

 

Filter사용 

@WebFilter + @ServletComponentScan

@ServletComponentScan
@SpringBootApplication
public class DemoApplication extends SpringBootServletInitializer {
    public static void main(String[] args) {
                SpringApplication.run(DemoApplication.class, args);

    }

 

@ServletComponentScan 어노테이션을 @SpringBootApplication 어노테이션이 설정되어 있는곳에 걸어준 다음 

 

@WebFilter("/filtered/*")
public class Filtered implements Filter {
    private Logger log = LoggerFactory.getLogger(Filtered.class);
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        log.info("doFilter MyFilter, uri : {}", ((HttpServletRequest)request).getRequestURI());
        System.out.println("Character encoding before : "+request.getCharacterEncoding());
        request.setCharacterEncoding("MS949");
        System.out.println("Character encoding after : "+request.getCharacterEncoding());
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

 

필터클래스에 @WebFilter 어노테이션을 설정해주면 아주 간단하게 끝이 난다. 

Filter를 통해 문자인코딩을 바꿔주는 코드를 작성하였다.

 

 

 

컨트롤러 설정 및 filtered와 일반 success 비교

@Controller
public class HelloController {

	@GetMapping("/success")
    public String success(Model model){
        System.out.println("success!!!");
        return "success";
    }

    @GetMapping("/filtered/success")
    public String filteredSuccess(Model model){
        System.out.println("filtered success!!!");
        return "filtered";
    }
}

 

 

 

필터링 url , 필터를 통해 문자인코딩이 바뀌었다

 

 

일반 url 

반응형

댓글