Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- Greedy
- Spring Boot
- 백준
- 자바
- Thymeleaf
- AOP
- 스프링
- Exception
- SpringBoot
- pointcut
- QueryDSL
- JPQL
- http
- springdatajpa
- transaction
- Proxy
- 그리디
- 스프링 핵심 원리
- 인프런
- 김영한
- db
- kotlin
- Servlet
- 알고리즘
- spring
- 스프링 핵심 기능
- java
- JDBC
- Android
- jpa
Archives
- Today
- Total
개발자되기 프로젝트
[로그인] ArgumentResolver 활용 본문
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
'인프런 > [인프런] 스프링 MVC 2' 카테고리의 다른 글
[예외] Servlet 예외처리 - 오류화면 등록 (0) | 2021.09.27 |
---|---|
[예외처리] Servlet 예외처리 (0) | 2021.09.27 |
[로그인] Spring Interceptor - 인증 체크 (0) | 2021.09.27 |
[로그인] Spring Interceptor - 요청 로그 (0) | 2021.09.26 |
[로그인] 스프링 인터셉터 (0) | 2021.09.26 |
Comments