Backend/Spring

[Spring] ArgumentResolver 사용하기

누구세연 2024. 7. 20. 11:39

ArgumentResolver는 Spring MVC에서 컨트롤러 메서드의 매개변수를 해석하고 주입하는 기능입니다.

컨트롤러에서 @RequestParam, @PathVariable를 사용하여 쿼리 파라미터나 경로 변수를 바인딩할 수 있고, 요청 본문을 바인딩하려면 @RequestBody를 사용합니다.

하지만 Header, Session, Cookie 등의 방식의 데이터를 바인딩해야 할 때는 어떻게 해야 할까요? 🧐

이때, ArgumentResolver를 사용하면 이러한 직접적이지 않은 방식의 데이터도 간편하게 가져올 수 있습니다.

 

 

ArgumentResolver 구현하기

Custom ArgumentResolver를 구현해 보며 개념을 살펴보겠습니다.

예를 들어, 클라이언트 요청에서 특정 헤더 값을 읽어와서 컨트롤러 메서드 매개변수로 주입하는 ArgumentResolver를 구현해 보겠습니다.

import org.springframework.core.MethodParameter;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

public class CustomHeaderArgumentResolver implements HandlerMethodArgumentResolver {

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(CustomHeader.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, 
                                  ModelAndViewContainer mavContainer, 
                                  NativeWebRequest webRequest, 
                                  WebDataBinderFactory binderFactory) throws Exception {
        CustomHeader customHeader = parameter.getParameterAnnotation(CustomHeader.class);
        return webRequest.getHeader(customHeader.value());
    }
}
  • HandlerMethodArgumentResolver 인터페이스
    Spring MVC에서 컨트롤러 메서드 매개변수를 해석하기 위해 구현하는 인터페이스입니다.
    supportsParameter와 resolveArgument 메서드를 구현해야 합니다.
    • supportsParameter
      해당 ArgumentResolver가 특정 매개변수를 지원하는지 여부를 반환합니다.
    • resolveArgument
      실제 매개변수를 해석하고 값을 반환합니다.

 

ArgumentResolver가 매핑할 사용자 정의 어노테이션을 정의합니다.

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomHeader {
    String value();
}

 

Spring MVC 설정 파일에서 ArgumentResolver를 등록합니다.

import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

@Configuration
public class WebConfig implements WebMvcConfigurer {

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

 

이제 컨트롤러에서 정의한 어노테이션을 사용하여 헤더 값을 매개변수로 받을 수 있습니다.

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class MyController {

    @GetMapping("/header")
    public String getHeaderValue(@CustomHeader("X-Custom-Header") String headerValue) {
        return "Header value: " + headerValue;
    }
}

 

 

요약
1. Custom ArgumentResolver 만들기: 특정 매개변수를 처리할 로직을 작성합니다.
2. Annotation 만들기: 매개변수에 사용할 어노테이션을 정의합니다.
3. ArgumentResolver 등록하기: Spring 설정 파일에 ArgumentResolver를 등록합니다.
4. 컨트롤러에서 사용하기: 컨트롤러 메서드에서 사용자 정의 어노테이션을 사용하여 매개변수를 주입받습니다.

 

ArgumentResolver를 활용하면 더 깔끔하고 유지보수하기 쉬운 코드를 작성할 수 있습니다🙂