Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

[로그인] ArgumentResolver 활용 본문

인프런/[인프런] 스프링 MVC 2

[로그인] ArgumentResolver 활용

Seung__ 2021. 9. 27. 20:28
 

RequestMapping Handler Adapter 구조

HTTP 메시지 컨버터는 SpringMVC 어디 쯤? 에서 사용됨....? 1. SpringMVC 구조 @RequestMapping을 처리하는 핸들러 Adapter인 RequestMappingHandlerAdapter에서 처리함. 2. RequestMappingHandlerAdapter 동작..

bsh-developer.tistory.com

 

1. @Login annotation을 직접 만들자?


  • 기존에는 @SessionAttribute()를 Member에 붙여서 Member와 관련있는 Session을 편하게 사용하였다.
  • @SessionAttribute()는 request에서 session을 꺼내주고 쿠키까지 찾아준다. 충분히 편리하다.
   // @GetMapping("/")
    public String homeLoginV3Spring(
            @SessionAttribute(name = SessionConst.LOGIN_MEMBER, required = false) Member loginMember, Model model){

        //세션에회원 정보가 없는 경우. -> 일반 home
        if(loginMember == null){
            return "home";
        }

        //세션에 회원 정보가 있는 경우.-> login home
        model.addAttribute("member", loginMember);
        return "loginHome";

    }
  • 하지만 매번 작성해주는게 여간 불편한게 아니다.
  • @Login이라는 annotaion을 만들어서 @SessionAttribute()를 대체하고, ArgumentResolver를 활용하자.

 

 

2. @Login


  • @Target(ElementType.PARAMETER) : 파라미터에만 사용
  • @Retention(RetentionPolicy.RUNTIME) : 리플렉션 등을 활용할 수 있도록 런타임까지 애노테이션
    정보가 남아있음
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME) //동작할때까지 annotation남아있음.
public @interface Login {


}

 

 

 

3. LoginMemberArgumentResolver


 

  • HandlerAdaptor에서 각 Handler(Controller)에 맞는 객체, 파라미터를 넘겨주기 위해 ArgumentResolver가 작동
  • 대부분 우리가 주로 사용하는 방식에 대해서는 이미 Spring이 잘 만들어 놓았다.
  • 하지만 @Login을 적용한 방식은 ArgumentResolver가 없기 때문에 새로 만들어 줘야한다.
  • ArgumentResolver
    • supportsParameter() 를 호출해서 해당 파라미터를 지원여부 확인
    • 지원하면 resolveArgument() 를 호출해서 실제 객체를 생성한다. 
    • 그리고 이렇게 생성된 객체가 컨트롤러 호출시 넘어감.
@Slf4j
public class LoginMemberArgumentResolver implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter parameter) {

        log.info("supportsParameter 실행");

        boolean hasLoginAnnotation = parameter.hasParameterAnnotation(Login.class);
        boolean hasMemberType = Member.class.isAssignableFrom(parameter.getParameterType());

        return hasLoginAnnotation && hasMemberType;
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {

        log.info("resolveArgument 실행");

        HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();
        HttpSession session = request.getSession(false);
        if(session == null){
            return null;
        }

        return session.getAttribute(SessionConst.LOGIN_MEMBER);

    }
}
  • supportsParameter() :
    • 넘어온 methodParamter에 @Login 애노테이션 있는지 확인.
    • 넘어온 methodParamter에서 parameter타입이 MemberClass(@Login붙은 클래스) 인지 확인.
    • 두 경우 모두 만족할 경우에 supportParameterm()는 true를 반환.
  • resolveArgument() : 
    • supportsParameter()에서 true를 반환했기 때문에, 
    • 컨트롤러 호출 직전에 호출 되어서 필요한 파라미터 정보를 생성해줌.
    • wepRequest에서 nativeRequest를 받아 HttpServletRequest로 casting해줌.
    • request에서 session에 있는 로그인 회원 정보 member 객체를 찾아서 반환
    • 이후 스프링MVC는 컨트롤러의 메서드를 호출하면서 여기에서 반환된 member 객체를 파라미터에 전달해준다

 

 

 

4. ArgumentResolver 등록


  • 진짜 간단...
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(new LoginMemberArgumentResolver());
    }
    
 }

 

 

5. 정리 


  • 실행해보면, 결과는 동일하지만, 훠어어어어일씬 편리하게 로그인 회원 정보를 조회할 수 있음.
  •  ArgumentResolver 를 활용하면 공통 작업이 필요할 때 컨트롤러를 더욱 편리하게 사용

 

 

6. GitHub : 210927 Login, ArgumentResolver


 

GitHub - bsh6463/login

Contribute to bsh6463/login development by creating an account on GitHub.

github.com

 

Comments