개요
본 포스팅은 호돌맨의 요절복통 개발쇼 (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
복사
다음과 같은 컨트롤러 메소드가 있다고 가정해봅시다.
우리는 우선 WebConfig에 ArgumentResolver를 등록해주어야 합니다.
@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
복사