🌱 Spring MVC (12) custom annotation을 μ΄μš©ν•œ ArgumentResolver ν™œμš©

Kim Dae HyunΒ·2021λ…„ 7μ›” 17일
0

Spring-MVC

λͺ©λ‘ 보기
10/13
post-thumbnail

Github μ†ŒμŠ€μ½”λ“œ

πŸ”Ž Custom Annotationλ₯Ό μ΄μš©ν•œ ArgumentResolver 적용

@GetMapping("/")
public String homeLogin(
        @SessionAttribute(name="SESSION_KEY", required = false) Member member, Model model) {

    if (member == null) return "home";

    model.addAttribute("member", member);
    return "loginHome";
}

μœ„ μ½”λ“œλŠ” 적용 μ „ μ½”λ“œμž…λ‹ˆλ‹€. λ¨Όμ € 적용 ν›„ μ½”λ“œλ₯Ό λ³΄μ‹œμ£ .

@GetMapping("/")
public String homeLoginV4(@Login Member member, Model model) {
    if (member == null) return "home";
    model.addAttribute("member", member);
    return "loginHome";
}

@Login μ΄λΌλŠ” μ–΄λ…Έν…Œμ΄μ…˜μœΌλ‘œ Member에 λŒ€ν•΄ 적용 μ „ μ½”λ“œμ™€ λ™μΌν•œ κ²°κ³Όλ₯Ό λ§Œλ“€μ–΄ λƒ…λ‹ˆλ‹€.

πŸ”Ž custom annotation μ •μ˜

μ–΄λ…Έν…Œμ΄μ…˜ μ •μ˜λŠ” interface μ•žμ— @λ₯Ό λΆ™μ—¬μ€˜μ•Ό ν•©λ‹ˆλ‹€. μ•„λž˜ μ–΄λ…Έν…Œμ΄μ…˜μ€ @Login이 λ˜λŠ” 것 μž…λ‹ˆλ‹€.

public @interface Login

μ–΄λ…Έν…Œμ΄μ…˜ μ„€μ •

  • @Target은 μ •μ˜ν•œ μ–΄λ…Έν…Œμ΄μ…˜μ΄ 뢙을 수 μžˆλŠ” νƒ€μž…μ„ μ •μ˜ν•˜λŠ” λΆ€λΆ„μž…λ‹ˆλ‹€.
  • PARAMETER λŠ” νŒŒλΌλ―Έν„°μ— 뢙을 수 μžˆλŠ” μ–΄λ…Έν…Œμ΄μ…˜μ΄λΌλŠ” μ˜λ―Έμž…λ‹ˆλ‹€.
    • @Target(ElementType.PARAMETER)
  • @Retention 은 μ–΄λ…Έν…Œμ΄μ…˜μ΄ μ–΄λ””κΉŒμ§€ λ©”λͺ¨λ¦¬λ₯Ό μœ μ§€ν•  지에 λŒ€ν•œ μ„€μ •μž…λ‹ˆλ‹€. κ°„λ‹¨ν•˜κ²Œ μ–΄λ…Έν…Œμ΄μ…˜μ˜ 생λͺ…μ£ΌκΈ°λ₯Ό μ„€μ •ν•΄μ€€λ‹€κ³  생각해도 될 것 κ°™μŠ΅λ‹ˆλ‹€.
  • RetentionPolicy.RUNTIME은 싀행될 λ•ŒκΉŒμ§€ μ–΄λ…Έν…Œμ΄μ…˜μ„ μœ νš¨ν•˜κ²Œ ν•˜κ² λ‹€λŠ” μ •μ±… μ„€μ •μž…λ‹ˆλ‹€.
    • @Retention(RetentionPolicy.RUNTIME)


πŸ”Ž ArgumentResolver 직접 κ΅¬ν˜„

ArgumentResolver λ₯Ό 직접 κ΅¬ν˜„ν•˜λ €λ©΄ HandlerMethodArgumentResolver μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•΄μ•Ό ν•©λ‹ˆλ‹€.

public class LoginArgumentResolver implements HandlerMethodArgumentResolver

HandlerMethodArgumentResolver κ΅¬ν˜„ λ©”μ„œλ“œλŠ” μ•„λž˜μ™€ 같이 supportParameter와 resolveArguent 두 κ°œμž…λ‹ˆλ‹€.

supportParameter

첫 번째 κ΅¬ν˜„ λ©”μ„œλ“œμΈ supportParameterλŠ” 받은 νŒŒλΌλ―Έν„°λ₯Ό μ²˜λ¦¬ν•  수 μžˆλŠ”μ§€ κ²€μ¦ν•˜λŠ” μ—­ν• μž…λ‹ˆλ‹€.

  • 검증해야 ν•  사항
    • @Login μ–΄λ…Έν…Œμ΄μ…˜μ΄ 뢙은 νŒŒλΌλ―Έν„°μΈμ§€
    • Member νƒ€μž…μΈμ§€

μ–΄λ…Έν…Œμ΄μ…˜μ— λŒ€ν•œ 검증을 μœ„ν•΄ MethodParameterλŠ” hasParameterAnnotation λ©”μ„œλ“œλ₯Ό μ§€μ›ν•©λ‹ˆλ‹€.

boolean hasLoginAnnotation = parameter.hasParameterAnnotation(Login.class);

νƒ€μž…μ— λŒ€ν•œ 검증은 getParameterType을 μ΄μš©ν•©λ‹ˆλ‹€.
isAssignableFrom은 νŒŒλΌλ―Έν„°μ˜ 클래슀 νƒ€μž…μ΄ μžμ‹ μ΄κ±°λ‚˜ μžμ‹ μ„ 상속/κ΅¬ν˜„ν–ˆλŠ”μ§€ κ²€μ¦ν•˜λŠ” λ©”μ„œλ“œμž…λ‹ˆλ‹€.

boolean isMemberType = Member.class.isAssignableFrom(parameter.getParameterType());

두 검증을 λ§Œμ‘±ν•œ κ²½μš°μ—λ§Œ resolveArgument λ©”μ„œλ“œκ°€ μ‹€ν–‰λ©λ‹ˆλ‹€.

return hasLoginAnnotation && isMemberType;

resolveArgument

μš”μ²­μ— λŒ€ν•œ μ„Έμ…˜μ„ 검증해야 ν•˜λ―€λ‘œ HttpServletRequestλ₯Ό μ΄μš©ν•΄ μ„Έμ…˜ 정보λ₯Ό κ°€μ Έμ˜¨ ν›„ 검증을 μˆ˜ν–‰ν•©λ‹ˆλ‹€.

HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();
HttpSession session = request.getSession(false);

if (session == null) return null;

리턴은 μ„Έμ…˜μ— λ‹΄κΈ΄ Member μž…λ‹ˆλ‹€.

return (Member) session.getAttribute("SESSION_KEY";

ArgumentResolverκ°€ 호좜되면 κ°€μž₯ λ¨Όμ € supportParameterλ₯Ό 톡해 νŒŒλΌλ―Έν„° 지원 μ—¬λΆ€λ₯Ό ν™•μΈν•˜κ³  μ§€μ›ν•œλ‹€λ©΄ resolveArgumentλ₯Ό ν˜ΈμΆœν•˜μ—¬ μ‹€μ œ 객체λ₯Ό μƒμ„±ν•˜μ—¬ ν˜ΈμΆœν•œ 곳의 객체에 바인딩 μ‹œμΌœμ£ΌλŠ” 것 μž…λ‹ˆλ‹€.

μΈν”„λŸ° κΉ€μ˜ν•œλ‹˜μ˜ μŠ€ν”„λ§ MVC 2편 을 μˆ˜κ°•ν•˜κ³  μ •λ¦¬ν•œ λ‚΄μš©μž…λ‹ˆλ‹€.

profile
μ’€ 더 천천히 까먹기 μœ„ν•΄ κΈ°λ‘ν•©λ‹ˆλ‹€. 🧐

0개의 λŒ“κΈ€