Search

ArgumentResolver란

Tags
ArgumentResolver
Date
2023/10/08

개요

본 포스팅은 호돌맨의 요절복통 개발쇼 (SpringBoot, Vue.JS, AWS) 를 기반으로 학습한 내용을 정리하였습니다. 앞 전의 요청 인증 값 확인 과 이어지는 내용이니 읽고 오시면 수월한 이해가 가능합니다.

1. ArgumentResolver란?

공식 문서에 나오는 정의는 다음과 같습니다.
컨트롤러의 메소드의 인자로 사용자가 임의의 값을 전달하는 방법을 제공하고자 할 때 사용됩니다.
 네..?
어려운 내용은 아니지만 예제를 보면 보다 더 수월하게 이해할 수 있습니다.
공식 문서는 임의의 값을 전달한다고 설명 하였지만 한번 상황을 만들어볼까요?
만약 권한이 있는 사용자/mypage 경로를 통해 사용자의 정보를 출력해야 한다고 가정 해봅시다.
/mypage를 매핑하고 있는 컨트롤러 메소드에 사용자의 정보를 전달하고자 합니다.
그 역할을 ArgumentResolver가 해주는 것입니다.

2. ArgumentResolver 작성 방법

ArgumentResolver는 다음과 같이 작성할 수 있습니다.
1.
HandlerMethodArgumentResolver를 구현한 클래스를 작성합니다.
public class AuthResolver implements HandlerMethodArgumentResolver { ... }
Java
복사
2.
supportsParmeter()resolveArgument() 메소드를 오버라이드 합니다.
public class AuthResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter parameter) { return false; } @Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { return null; } }
Java
복사
3.
WebMcvConfig에 Resolver를 추가합니다.
@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { resolvers.add(new AuthResolver()); } }
Java
복사

3. ArgumentResolver 응용

1번에서 말했던 상황을 재현해보겠습니다.
@RestController public class UserController { @GetMapping("/mypage") public String mypage(UserSession userSession) { return "UserID: " + userSession.getUserId() + ", UserName: " + userSession.getUserName(); } }
Java
복사
다음과 같은 컨트롤러 메소드가 있다고 가정해봅시다.
우리는 우선 WebConfigArgumentResolver를 등록해주어야 합니다.
@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { resolvers.add(new AuthResolver()); } }
Java
복사
다음으로 ArgumentResolver를 커스텀 해 줄 차례입니다.
@Component public class UserSessionArgumentResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter parameter) { return parameter.getParameterType().equals(UserSession.class); } @Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { return new UserSession("1234", "JohnDoe"); } }
Java
복사
supportParameter()UserSession.class를 가지고 있는 메소드를 검사합니다.
만약 UserSession.class을 파라미터로 가지고 있는 메소드는 위 메소드에서 true를 반환합니다.
true를 반환한다면 resolveArgument() 메소드가 실행됩니다.
메소드를 보면 UserSession 객체를 만들어 반환하는 것을 확인할 수 있습니다.
따라서 실행 흐름은 다음과 같습니다.
/mypage 경로에 접속
→ mypage() 메소드 실행
→ ArgumentResolver가 해당 메소드가 UserSession을 파라미터로 가지고 있는지 확인
→ 가지고 있다면 UserSession 객체에 원하는 값을 넣어 반환
만약 권한이 있는지 검사하고 값을 넘겨주겠다면 다음과 같이 고칠 수도 있습니다.
@Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { // AccessToken을 검사 String accessToken = webRequest.getParameters("accessToken"); if(accessToken != null && accessToken.eqauls("auth"){ // 데이터베이스에서 유저 정보를 조회 후 UserSession에 반환 return userSession; } return null; }
Java
복사