컨트롤러의 메서드 파라미터로 들어오는 데이터를 자동으로 가공하고 바인딩해주는 도구
@RequestParam, @RequestBody, @RequestHeader, @PathVariable 등 어노테이션이 내부적으로 ArgumentResolver를 통해 동작한다.다음의 절차로 커스텀 ArgumentResolver를 구현할 수 있다.
HandlerMethodArgumentResolver 인터페이스 구현supportsParameter() 메소드 구현 (언제 실행할지 결정)resolveArgument() 메소드 구현 (무엇을 만들어줄지 결정)WebMvcConfigurer에 등록CustomPathVariable.java 작성)@Target(ElementType.PARAMETER) // 컨트롤러 메서드의 '파라미터'를 타겟으로 동작
@Retention(RetentionPolicy.RUNTIME) // 런타임을 수명으로 가짐
public @interface CustomPathVariable {
String value() default "";
boolean required() default true;
}
1-3. HandlerMethodArgumentResolver 인터페이스 및 내부 메서드 구현
public class CustomPathVariableArgumentResolver implements HandlerMethodArgumentResolver {
// `supportsParameter()` 메소드 구현 (언제 실행할지 결정)
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(CustomPathVariable.class);
// 파라미터가 CustomPathVariable 어노테이션을 가지고 있다면 동작하겠다!
}
// `resolveArgument()` 메소드 구현 (무엇을 만들어줄지 결정)
@Override @SuppressWarnings("all")
public Object resolveArgument(
@NonNull MethodParameter parameter,
ModelAndViewContainer mavContainer,
@NonNull NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) {
CustomPathVariable annotation = parameter.getParameterAnnotation(CustomPathVariable.class);
String variableName = annotation.value().isEmpty() ? parameter.getParameterName() : annotation.value();
// path 값을 가져와서
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
Map<String, String> uriTemplateVars =
(Map<String, String>) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
// 규칙에 따라 값들을 매핑한 뒤
String value = uriTemplateVars.get(variableName);
return value == null ? null : new SimpleTypeConverter().convertIfNecessary(value, parameter.getParameterType());
// 필요한 값을 반환
}
}
WebMvcConfigurer에 등록@Configuration
public class CustomWebMvcConfig implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new CustomPathVariableArgumentResolver());
}
}
@RestController
public class TestController {
@GetMapping("/path/{id}")
public String pathVariableTest(@CustomPathVariable Long id) {
return "id=" + id;
}
}
