Updated:

1. 개요

Argument Resolver는 컨트롤러로 들어온 파라미터를 가공 및 수정할 수 있도록 기능을 제공해주는 객체이다. Argument Resolver를 통해 중복되는 코드를 깔끔하게 사용할 수 있다. 이번에는 Argument Resolver를 사용하는 방법에 대해 알아보도록 하자.

2. 개발 환경

  • Java 11

  • Spring Boot 2.7.5

3. 예제 코드

[Member.java]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Data
public class Member {

    private Long id;

    @NotEmpty
    private String loginId; // 로그인 ID

    @NotEmpty
    private String name; // 사용자 이름

    @NotEmpty
    private String password;
}

[HomeController.java]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Slf4j
@Controller
@RequiredArgsConstructor
public class HomeController {

    @GetMapping("/")
    public String homeLoginV3ArgumentResolver(@Login Member loginMember, Model model) {
        // 세션에 회원 데이터가 없으면 home
        if(loginMember == null) {
            return "home";
        }

        // 세션이 유지되면 이동
        model.addAttribute("member", loginMember);
        return "loginHome";
    }
}

[Login.java]

1
2
3
4
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface Login {
}

[SessionConst.java]

1
2
3
4
5
public class SessionConst {

    public static final String LOGIN_MEMBER = "loginMember";
}

[LoginMemberArgumentResolver.java]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@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;
        }
        Object member = session.getAttribute(SessionConst.LOGIN_MEMBER);
        return member;
    }
}

Line 4 ~ 10 : @Login Annotation이 있고, Member 타입이면 해당 ArgumentResolver 사용

Line 12 ~ 22 : 컨트롤러 호출 직전 호출되어 필요한 파라미터 정보 생성

[WebConfig.java]

1
2
3
4
5
6
7
8
@Configuration
public class WebConfig implements WebMvcConfigurer {

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

Line 4 ~ 7 : LoginMemberArgumentResolver 등록

[template/loginHome.html]

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
32
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <link th:href="@{/css/bootstrap.min.css}"
          href="../css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container" style="max-width: 600px">
    <div class="py-5 text-center">
        <h2>홈 화면</h2> </div>
    <h4 class="mb-3" th:text="|로그인: ${member.name}|">로그인 사용자 이름</h4>
    <hr class="my-4">
    <div class="row">
        <div class="col">
            <button class="w-100 btn btn-secondary btn-lg" type="button"
                    th:onclick="|location.href='@{/items}'|">
                상품 관리
            </button>
        </div>
        <div class="col">
            <form th:action="@{/logout}" method="post">
                <button class="w-100 btn btn-dark btn-lg" type="submit">
                    로그아웃
                </button>
            </form>
        </div>
    </div>
    <hr class="my-4">
</div> <!-- /container -->
</body>
</html>

Updated:

Leave a comment