안녕하세요. INCHEOL'S 입니다.
오늘은 Spring MVC의 ArgumentResolver 를 추가하여 Handler Method의 Argument에 내가 원하는 값이 바인딩 되도록 해보겠습니다.
Spring MVC에서 지원하는 여러 ArgumentResolver들이 존재하고 우리가 필요로 하는 대부분의 것들을 지원하지만 하필 Spring에서 지원하지 않는 것들을 필요로 할 때가 있습니다.
이와 관련하여 ArgumentResolver를 추가해보는 예제를 만들어보고자 합니다.
기본적으로 스프링이 지원하는 Handler Argument 목록들을 한번 살펴보세요. 또한 각각의 Handler Argument들을 만들기 위한 ArgumentResolver들도 찾아보시는것도 좋은 공부가 될 것 같습니다.
그럼 시작하겠습니다.
저는 요청을 보낸 User의 IP 주소를 Handler Argument에서 바로 가져올 수 있도록 구성해보겠습니다.
먼저, HandlerMethodArgumentResolver 를 구현한 구현체, 그리고 RemoteAddr이라는 애너테이션을 작성했습니다.
public class MyArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return Objects.nonNull(parameter.getParameterAnnotation(RemoteAddr.class));
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
HttpServletRequest nativeRequest = (HttpServletRequest) webRequest.getNativeRequest();
String remoteAddr = nativeRequest.getRemoteAddr();
return remoteAddr;
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface RemoteAddr {
}
RemoteAddr 애너테이션이 붙어 있는 파라미터가 있다면 httpServletRequest의 remoteAddr을 가져와 리턴하도록 단순하게 구성하였습니다.
아! Annotaion을 작성하실 때 주의 사항은 @Retention 정책이 반드시 RUNTIME이여야 합니다. 왜냐하면 JVM에 클래스파일이 메모리에 올라가 기동된 시점이라면 RUNTIME 시점인데 이 시점에 반드시 애너테이션 정보가 살아있어야 우리가 만든 ArgumentResolver에서 정상적으로 판단할 수 있기때문입니다.
그 다음, MyArgumentResolver를 WebMvcConfigurer를 이용하여 ArgumentResolvers 리스트에 추가해줬습니다.
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new MyArgumentResolver());
}
}
자, 이제 모든 설정은 끝났습니다.
사용할 컨트롤러를 작성하여 테스트해보겠습니다. 아래와 같이 간단하게 받은 파라미터를 바로 리턴하도록 만들고~
@RestController
@RequestMapping("/argumentResolver")
public class DefaultArgumentController {
@GetMapping("/remoteAddr")
public String remoteAddr(@RemoteAddr String ip) {
return ip;
}
}
Postman 툴을 이용하여 요청을 날려보겠습니다.
짠!~ 제가 원하는 대로 클라이언트의 아이피가 리턴되었습니다.
아주 간단하죠?!