Free Lines Arrow
본문 바로가기
Spring/spring mvc 2 스터디

[Spring] Filter

by skahn1215 2022. 5. 31.
728x90
반응형

서블릿 필터

  • 필터는 서블릿이 지원하는 필터이다.
  • 서블릿을 호출하기 전 필터를 사용하여 전처리를 할 수 있다.
  • 필터는 서블릿의 영역이다.

 

필터의 동작 방식

 

필터 흐름

  • 필터의 기본적인 흐름
HTTP 요청 -> WAS -> 필터 -> 서블릿 -> 컨트롤러

 

필터 제한

  • 필터에 제한을 두어 서블릿을 호출 하지 않게 할 수 있다.
HTTP 요청 -> WAS -> 필터 (적절하지 않을 경우 여기서 중단)

 

필터 체인

  • 필터를 여러개 중복해서 사용할 수 있다.
HTTP 요청 ->WAS-> 필터1-> 필터2-> 필터3-> 서블릿 -> 컨트롤러

 

 

 

필터의 인터 페이스의 메소드

init(): 필터 초기화 메서드

public default void init(FilterConfig filterConfig) throws ServletException

 

 

doFilter(): 고객의 요청이 올 때 마다 해당 메서드가 호출된다.

public void doFilter(ServletRequest request, ServletResponse response,
              FilterChain chain) throws IOException, ServletException;

 

destroy(): 필터 종료메서드, 서블릿 컨테이너가 종료될때 호출 된다.

public default void destroy() {}

 

 

 

필터의 구현 과정

  • 필터 인터페이스 구현
  • WebConfig(@Configuration이 붙은 클래스) 에 필터 등록

 

로그 필터 구현

  • doFilter: 요청이 올때 해당 메소드 가 호출 된다.
  • chain.doFilter(request, response);
    - 다음 필터가 있으면 필터를 호출하고 없으면 서블릿을 호출 한다.
@Slf4j
public class LogFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("log filter init");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        log.info("log filter doFilter");

        // 다운 캐스팅 필요 기능이 별로 없기 때문에
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String requestURI = httpServletRequest.getRequestURI();

        String uuid = UUID.randomUUID().toString();

        try {
            log.info("REQUEST [{}][{}]", uuid, requestURI);

            // doFitler 를 안하면 서블릿으로 넘어가지 않는다.
            chain.doFilter(request, response);
        } catch (Exception e) {
            throw e;
        } finally {
            log.info("RESPONSE");
        }

    }


    @Override
    public void destroy() {
        log.info("log filter destroy");
    }
}

 

필터 설정

@Configuration
public class WebConfig {

    @Bean
    public FilterRegistrationBean logFilter() {
        FilterRegistrationBean<Filter> filterFilterRegistrationBean = new FilterRegistrationBean<>();

        //필터 등록
        filterFilterRegistrationBean.setFilter(new LogFilter());

        // 필터 우선순위 설정
        filterFilterRegistrationBean.setOrder(1);

        // 필터를 적용할 요청 URL
        filterFilterRegistrationBean.addUrlPatterns("/*");

        filterFilterRegistrationBean.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ERROR);

        return filterFilterRegistrationBean;
    }
}

 

 

로그인 체크 필터 구현

  • 필터를 상속받아 구현을 한다.
  • 동일하게 webconfig 에 등록을 해주면 된다.
public class LoginCheckFilter implements Filter {

    private static final String[] whiteList = {"/", "/login", "/members/add", "/logout", "/css/*"};

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String requestURI = httpRequest.getRequestURI();

        HttpServletResponse httpResponse = (HttpServletResponse)response;

        try {
            log.info("인증 체크 필터 시작 {}", requestURI);
            if (isLoginCheckPath(requestURI)) {
                log.info("인증 케트 로직 실행", requestURI);
                HttpSession session = httpRequest.getSession(false);

                if (session == null || session.getAttribute(SessionConst.LOGIN_MEMBER) == null) {

                    log.info("미인증 사용자임", requestURI);
                    // 로그인 페이지로 보내버린뒤 다시 조회할 페이지를 넣어준다.
                    httpResponse.sendRedirect("/login?redirectURL=" + requestURI);
                    return;
                }
            }
            chain.doFilter(request,response);
        } catch (Exception e) {
            throw e; // 예외 로깅 가능 하지만, 톰캣 까지 예외를 보내줘야 함.
        } finally {
            log.info("인증 체크 필터 종료 {}", requestURI);
        }
    }

    /**
     * 화이트 리스트의 경우 인증 체크 X
     */

    private boolean isLoginCheckPath(String requestURI) {
        return !PatternMatchUtils.simpleMatch(whiteList, requestURI);
    }

 

중요부분

  • 필터안에서 리턴을 해버리면 다음단계 즉 서블릿을 호출 단계 까지 가진 않는다.
if (session == null || session.getAttribute(SessionConst.LOGIN_MEMBER) == null) {
    log.info("미인증 사용자임", requestURI);
    // 로그인 페이지로 보내버린뒤 다시 조회할 페이지를 넣어준다.
    httpResponse.sendRedirect("/login?redirectURL=" + requestURI);
    return; // 필터안에서 그냥 리턴을 할 경우 다음으로 진행되지 않는다.
}

 

 

 

 

 

참고:

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-2/lecture/83352?tab=curriculum&volume=1.00 

 

스프링 MVC 2편 - 백엔드 웹 개발 활용 기술 - 인프런 | 학습 페이지

지식을 나누면 반드시 나에게 돌아옵니다. 인프런을 통해 나의 지식에 가치를 부여하세요....

www.inflearn.com

 

728x90
반응형

'Spring > spring mvc 2 스터디' 카테고리의 다른 글

[Spring] Filter Vs Interceptor  (0) 2022.06.01
[Spring] Interceptor  (0) 2022.06.01
[Spring] 로그인 처리 세션  (0) 2022.05.25
[Spring] 로그인 처리 쿠키  (0) 2022.04.16
[Spring] Validation: Validator  (0) 2022.02.02

댓글