토이 프로젝트에서 HttpServletRequest
에서 유저 정보를 추출하는 로직이 공통으로 필요한데,
어떻게 처리하면 좋을지 찾아보다가 회사에선 HandlerMethodArgumentResolver
를 사용하길래 관련된 내용들을 기록해 두고자 한다. 🤍 🫧
Annotation
을 통해 메소드 파라미터로 호출하면 자동으로 바인딩 되는 기술supportsParameter()
true
를 리턴하는 경우, argument resolve
가 시작된다.resolveArgument()
@Target(AnnotationTarget.VALUE_PARAMETER)
@Retention(AnnotationRetention.RUNTIME)
annotation class MemberDetails()
@Target(AnnotationTarget.VALUE_PARAMETER)
@Target
어노테이션은 Java Compiler
가 어노테이션이 어디에 적용될지 결정하기 위해 사용한다. AnnotationTarget.VALUE_PARAMETER
@Retention(AnnotationRetention.RUNTIME)
@Retention
어노테이션은 어노테이션이 남아있는 단계를 선정한다.RUNTIME
으로 선언하면 런타임 중에 어노테이션 정보가 남아있다.@Component
class MemberDetailsArgumentResolver : HandlerMethodArgumentResolver {
override fun supportsParameter(parameter: MethodParameter): Boolean {
return parameter.hasParameterAnnotation(MemberDetails::class.java)
}
override fun resolveArgument(parameter: MethodParameter, mavContainer: ModelAndViewContainer?, webRequest: NativeWebRequest, binderFactory: WebDataBinderFactory?): Any? {
val request = webRequest.nativeRequest as HttpServletRequest
val memberDetails = request.getAttribute("_memberDetails") as CustomUserDetails
return MemberDetailsVO(userName = memberDetails.userName)
}
}
parameter.hasParameterAnnotation(MemberDetails::class.java)
MemberDetails
어노테이션을 사용했는지 여부를 판단한다. @Nullable
Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception;
@Configuration
class WebMvcConfig @Autowired constructor(
private val authInterceptor: AuthInterceptor,
private val memberDetailsArgumentResolver: MemberDetailsArgumentResolver
) : WebMvcConfigurer {
/* .. 생략 .. */
override fun addArgumentResolvers(resolvers: MutableList<HandlerMethodArgumentResolver>) {
resolvers.add(memberDetailsArgumentResolver)
}
}
@PostMapping
fun saveAccountLog(httpServletRequest: HttpServletRequest, @MemberDetails member: Member, @RequestBody accountLogSaveRequest: AccountLogSaveRequest): ResponseEntity<ResponseDto<AccountLogSaveResponse>> {
return accountLogService.saveAccountLog(httpServletRequest, member, accountLogSaveRequest)
}
@MemberDetails
커스텀 어노테이션을 사용하면 member
정보를 사용할 수 있다.출처
[Spring/Springboot]HandlerMethodArgumentResolver를 통해 Controller의 파라미터 자동처리하기
HandlerMethodArgumentResolver 란
[Spring Boot] Meta Annotation (@Target, @Retention)
[kotlin] 코틀린 차곡차곡 - 11. Annotation ( 어노테이션 )
[Spring] ArgumentResolver 추가 방법 (kotlin ver.)