새소식

반응형
Spring/etc

[Spring] HandlerMethodArgumentResolver 사용

  • -
반응형

HandlerMethodArgumentResolver는 Controller Method에서 특정 조건에 맞는 파라미터가 있을 때 원하는 값을 바인딩해 주는 인터페이스이다.

 

Spring 공식 문서에는 아래와 같이 설명되어있다.

Strategy interface for resolving method parameters into argument values in the context of a given request.
주어진 요청으로부터, method의 parameter를 argument로 주입해 주는 전략 패턴의 interface

 

Spring MVC를 작성할 때, Controller에 정의한 Method들에도 @PathVariable, @RequestParam을 사용하는데 이러한 것들도 모두 HandlerMethodArgumentResolver를 구현하여 작성한 기능들이다.

 

위의 코드는 org.springframework.web.servlet.mvc.method.annotation.RequestMa ppingHandlerAdapter의 코드로 Spring MVC에서 기본적으로 등록된 MethodArgumentResolver들이다.

 

간단하게 많이 사용하는 MethodArgumentResolver를 살펴보면 아래와 같다.

  • PathVariableMethodArgumentResolver
    • @PathVariable
  • RequestParamMethodArgumentResolver
    • @ReqeustParam

 

@Controller public class indexController{ private final HttpSession httpSession; @GetMapping("/") public String index(Model model){ User user = (User) httpSession.getAttribute("user"); if(user != null){ model.addAttribute("userName", user.getName()); } return "index"; } }

위의 예시에서 HttpSession에서부터 User를 가져오는 코드를 User가 필요한 모든 Controller의 Method에 작성하는 일은 중복 코드가 발생하고, 비효율적이다.

이러한 비효율성을 HandlerMehtodArguementResolver를 통해서 해결해 보자.

 

@RequiredArgsConstructor @Component public class LoginUserArgumentResolver implements HandlerMethodArgumentResolver { // 조건에 맞는 경우 메소드가 있다면 구현체가 지정한 값으로 해당 메소드의 파라미터를 넘길 수 있다 private final HttpSession httpSession; @Override public boolean supportsParameter(MethodParameter parameter) { // 컨트롤러 메서드의 특정 파라미터를 지원하는지 판단 // 파라미터 클래스 타입이 SessionUser인 경우 true 반환 boolean isUserClass = SessionUser.class.equals(parameter.getParameterType()); return isUserClass; } @Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { // 파라미터에 전달할 객체를 생성 return httpSession.getAttribute("user"); } }

여기서 사용된 SessionUser는 로그인 시 HttpSession에 담아놓은 사용자가 정의한 User Class이다. 

 

@RequiredArgsConstructor @Configuration public class WebConfig implements WebMvcConfigurer { private final LoginUserArgumentResolver loginUserArgumentResolver; @Override // HandlerMethodArgumentResolver는 항상 WebMvcConfigurer의 addArgumentResulvers()를 통해 추가해야 한다 public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { resolvers.add(loginUserArgumentResolver); } }

 

@Controller @RequiredArgsConstructor public class IndexController { private final PostsService PostsService; // private final HttpSession httpSession; @GetMapping("/") public String index(Model model, SessionUser user) { model.addAttribute("posts", PostsService.findAllDesc()); // SessionUser user = (SessionUser) httpSession.getAttribute("user"); if (user != null) { // 세선에 저장된 값이 있을 때만 model에 userName을 등록해 준다 model.addAttribute("userName", user.getName()); } return "index"; } }
반응형

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.