Spring MVC Configuration

ppparkta·2025년 5월 12일

Spring

목록 보기
7/7

Spring MVC Configuration

WebMvcConfigurer를 사용하면 개발자가 Spring MVC 설정을 유연하게 커스터마이징할 수 있다.

이 글에서는 다음 세 가지 항목을 다룬다:

  • View Controller 등록
  • Interceptor 추가
  • ArgumentResolver 커스터마이징

1. View Controllers

컨트롤러 로직 없이 단순히 뷰만 반환해야 하는 경우, addViewControllers()를 통해 간단히 매핑할 수 있다.

ParameterizableViewController를 내부적으로 사용하며, 로직 없이 뷰 이름만 반환할 때만 사용해야 한다.

예시로는 정적 페이지, 로그인 화면, 홈 화면 리다이렉트 등에 적합하다.

@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("hello");
    }
}

왜 쓰는가?

단순 뷰 매핑을 위해 굳이 @Controller를 만드는 게 과하다고 느껴질 때 간단히 설정 가능.

하지만 이 설정은 스프링을 모르는 개발자에겐 직관적이지 않기 때문에 한시적으로만 사용하는 게 좋다. 일반적인 경우엔 그냥 @Controller를 쓰자.

👉 공식 문서 링크


2. Interceptor

인터셉터는 HTTP 요청의 전후 처리에 사용할 수 있다. 예를 들어:

  • 로그인 체크
  • 접근 제한
  • 요청 로깅

등의 기능을 구현할 수 있다.

인터페이스 정의

public interface HandlerInterceptor {

    default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }

    default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }

    default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
    }
}

아래와 같이 사용할 수 있다.

@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new CheckLoginInterceptor())
                .addPathPatterns("/admin/**")
                .excludePathPatterns("/admin/login");
    }
}
public class CheckLoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        String accessToken = request.getHeader("Authorization");
        if (accessToken == null) {
            throw new AuthorizationException();
        }

        return true;
    }
}

패턴 문법 정리 (Ant 스타일)

패턴설명
/admin/*/admin/ 하위 한 단계만 매핑 (예: /admin/user)
/admin/**/admin/ 하위 모든 경로 매핑 (예: /admin/user/edit)
/**전체 요청 경로 매핑
/static/**.css/static/ 하위 .css 파일들
/*.html루트 경로의 .html 파일 (예: /index.html)

Filter와 Interceptor 차이

항목FilterInterceptor
위치ServletContainer 수준Spring DispatcherServlet 내부
대상모든 요청 (정적 리소스 포함)Spring MVC 처리 요청만
용도보안, 로깅 등 전역 기능컨트롤러 전후 처리
APIServlet 표준Spring 전용

⚠️ 보안 목적이라면 Interceptor가 아니라 Spring SecurityFilter를 써야 한다.
(아예 DispatcherServlet까지 도달하지 않은 요청에 대해선 아무런 제어권이 없기 때문)


3. ArgumentResolver

컨트롤러 메서드의 파라미터로 직접 값을 주입하고 싶을 때 사용하는 방식이다.

예를 들어 @Login이라는 커스텀 애노테이션을 만들고, 로그인한 사용자 ID를 자동으로 주입하고 싶을 때 유용하다.

인터페이스를 다음과 같이 구현할 수 있다.
supportsParameter()resolveArgument()를 오버라이딩해서 구현 가능하다.

public class LoginMemberArgumentResolver implements HandlerMethodArgumentResolver {

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(Login.class)
               && parameter.getParameterType().equals(Long.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter,
                                  ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest,
                                  WebDataBinderFactory binderFactory) {
        String memberId = webRequest.getHeader("X-MEMBER-ID");
        return memberId != null ? Long.parseLong(memberId) : null;
    }
}

위에서 구현한 Argument Resolver를 SpringMVC 구성에 추가한다.

@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(new LoginMemberArgumentResolver());
    }
}

프로덕션 코드에서 다음과 같이 활용 가능하다.

@GetMapping("/profile")
public String getProfile(@Login Long memberId) {
    return "Profile for memberId: " + memberId;
}

정리

항목설명
인터페이스HandlerMethodArgumentResolver
메서드supportsParameter(), resolveArgument()
등록 위치addArgumentResolvers() in WebMvcConfigurer
사용 예로그인 유저 정보, 공통 파라미터 처리 등
장점관심사 분리, 컨트롤러 코드 단순화

마무리

  • ViewController: 로직 없이 뷰만 응답할 때 유용. 설정은 간단하지만 가독성이 떨어질 수 있어 일반적으로는 @Controller가 더 나음.
  • Interceptor: 요청 전후 공통 로직 실행에 사용. 인증, 접근 제한 등. 단, 보안 용도로는 사용 X.
  • ArgumentResolver: 공통 파라미터 주입. 커스텀 애노테이션과 조합해 쓰면 매우 깔끔함.

참고

profile
겉촉속촉

0개의 댓글