스프링부트 인터셉터 사용하기

merci·2023년 2월 21일
0

Spring

목록 보기
11/21

스프링부트는 디스패처서블릿을 구현하고 있다.

디스패처서블릿의 역할중에서 공통처리가 있는데 사용자의 요청을 필터링을 하고 싶다면 인터셉터를 이용해서 디스패처서블릿에 처리내용을 입력할 수 있게 된다.

인터셉터를 사용하면 사용자의 요청이 컨트롤러를 호출하기 전과 후 , 사용자에게 응답을 하고 난 뒤에 공통처리를 할 수 있다.

인터셉터의 처리 과정

인터셉터를 사용하기 위해서는 HandlerInterceptor 을 구현하거나 HandlerInterceptorAdaptor을 상속한 클래스를 이용하면 된다.

이번 포스팅에서는 HandlerInterceptor 을 구현해서 인터셉터를 이용해본다.

사용자가 로그인을 하지 않았을 경우 로그인 페이지로 보내기 위해 인터셉터를 이용해보자.

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.lang.Nullable;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.example.loginexample.model.User;

public class CustomInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        // System.out.println("테스트 : "+ request.getRequestURL().toString());
        if (request.getRequestURL().toString().equals("http://localhost:8080/")) {
            User principal = (User) request.getSession(false).getAttribute("principal");
            if (principal == null) {
                response.sendRedirect("/login");
                return false;
            }
        }
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            @Nullable ModelAndView modelAndView) throws Exception {
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
            @Nullable Exception ex) throws Exception {
    }
}

HandlerInterceptor을 구현한 클래스를 하나 만들고 자동완성 기능을 이용하면 기본적인 틀이 만들어 진다.

컨트롤러의 매핑 이전에 세션을 검사해서 로그인 페이지로 보내기 위해서는 preHandle() 메소드에서 공통처리를 입력한다.

preHandle() 의 리턴이 true일 경우 컨트롤러가 호출되고 false 일경우 컨트롤러가 호출되지 않는다.

커스텀인터셉터를 사용하기 위해서는 스프링에 등록해야하는데 다음처럼 등록한다.

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import com.example.loginexample.interceptor.CustomInterceptor;

@Configuration
public class AppConfig implements WebMvcConfigurer {
 
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new CustomInterceptor())
        .addPathPatterns("/**") // 모든 URL에 대해 인터셉터를 수행하도록 설정합니다.
        .excludePathPatterns("/login", "/join"); // /login과 /register URL에 대해서는 인터셉터를 수행하지 않도록 설정합니다.
    }
}

등록할 인터셉터에 만든 인터셉터를 넣고나서 특정한 패턴들을 추가하면 사용자가 어떤 주소를 입력했을때 인터셉터를 발동할지 정할수 있다.

등록한 인터셉터에 따라서 로그인을 하지 않고 메인을 요청한다면 로그인폼으로 리다이렉션이 된다.

추가적으로 약간 다른 코드

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        String requestURI = request.getRequestURI();
        if (requestURI.startsWith("/user")) { // "/blocked"로 시작하는 요청을 차단
            User principal = (User) request.getSession(false).getAttribute("principal");
            if (principal == null) {
                response.sendRedirect("/user/login");
                return false;
            }
        }
        if (requestURI.startsWith("/comp")) { // "/blocked"로 시작하는 요청을 차단
            Comp compSession = (Comp) request.getSession(false).getAttribute("compSession");
            if (compSession == null) {
                response.sendRedirect("/comp/login");
                return false;
            }
        }
        return true;



WebMvcConfigurer 를 구현하는 이유

이전에는 WebMvcConfigurerAdapter를 이용해서 설정파일을 등록했었다. 현재 어뎁터클래스를 사용하지 않는 이유는 코드수정을 피하기 위함이고 위 인터페이스가 편하기 때문이다.

예전에 java GUI를 해보면서 키보드나 마우스 이벤트를 어뎁터클래스를 이용해서 필요한 내용만 재정의를 했었는데 여기서 어뎁터 클래스가 만들어진 이유를 알 필요가 있다.

어뎁터 클래스는 부모인터페이스를 미리 오버라이딩해서 재정의할 필요가 없게 만들고 필요한 메소드만 재정의해서 사용하기 쉽게 만들어 놓은 클래스이다.

만약 부모인터페이스에 새로운 메소드가 생기게 되면 어뎁터클래스 또한 새로운 재정의를 만들어야하게 되는데 자바 8버전에서부터 디폴트 메소드가 등장하게 되어 이 과정 또한 필요가 없어졌다.

재정의 할 필요가 없게됨으로서 확장성을 좋게 만들어주는데 이를 통해 오버라이딩을 하게 되는 어뎁터 클래스의 존재이유가 사라지게 되었다.
또한 기존 메소드앞에 디폴트를 붙이더라도 인터페이스를 사용하는 수많은 코드들이 수정할 필요가 없게 되어 인터페이스에 디폴트 메소드를 이용해서 기능추가하기가 아주 편해졌다.

따라서 현재는 디폴트 메소드를 이용한 WebMvcConfigurer 인터페이스를 이용하지 어뎁터 클래스를 이용하지는 않는다.

디폴트 메소드를 이용함으로서 OCP를 지키게 된다. - 확장성에 용이
디폴트 메소드를 이용함으로서 ISP또한 지키게 된다. - 인터페이스를 사용하는 코드들에 영향을 주지 않음
디폴트 메소드를 이용하면 해당 메소드를 구현해야하는 강제성이 없어지므로 필요한 메소드만 구현하면 된다. 아래처럼 말이다.

	@Override
    public void addInterceptors(InterceptorRegistry registry){}
profile
작은것부터

0개의 댓글