SpringBoot [스프링부트] 시작하기(7) ArgumentResolver 만들기
전 시간에 Controller에서 Session을 가져오는 데 있어서 중복 코드가 있었습니다. 해당 코드를 ArgumentResolver로 해결해보겠습니다.
ArgumentResolver란?
컨트롤러의 메소드의 인자로 사용자가 임의의 값을 전달하는 방법을 제공할 때 사용합니다. 저희가 활용할 부분은 세션에 저장되어 있는 것을 메소드의 파라미터로 넘겨주는 역할을 하게 됩니다.
1. argumentresolver 패키지 먼저 만듭니다.
SessionConst와 SessionDto를 사용하므로 Dto에 있던 것을 옮겨줍니다.
2. ArgumentResolver에 사용될 LoginUser Annotation만들기
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginUser {
}
- @Target: Annotation을 사용할 수 있는 곳을 정의합니다. Class, Parameter,Method,Field 등등 여러 가지 있습니다.
- @Retention: Annotation의 설정으로 Annotation의 라이프 사이클을 정의합니다. Source, Class, Runtime이 있습니다. 보통 Runtime을 사용하여 프로젝트가 실행 중에도 사용할 수 있도록 Annotation의 라이프 사이클을 정해줍니다.
3. ArgumentResolver
public class ArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
parameter.hasParameterAnnotation(LoginUser.class);
boolean hasLoginAnnotation = parameter.hasParameterAnnotation(LoginUser.class);
boolean hasOwnerType = SessionDto.class.isAssignableFrom(parameter.getParameterType());
return hasLoginAnnotation && hasOwnerType;
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();
HttpSession session = request.getSession(false);
if(session==null){
return null;
}
return session.getAttribute(SessionConst.LOGIN_MEMBER);
}
}
- supportsParameter: 우리가 받고자 파라미터가 조건을 만족하는지 확인합니다. 조건을 만족시키지 못할 시 false를 반환하며, resolveArgument()를 실행하지 않습니다.
1. @LoginUser Annotation이 붙었는지 확인합니다.
2. 정보를 넣고자 하는 SessionDto 클래스인지 확인합니다.
- resolveArgument: supportsParameter에서 true가 넘어올 시 실행됩니다.
1. NativeWebRequest를 HttpServletRequest로 형변환 합니다.
2. request.getSession(false)로 하여 session이 없다면 생성하지 않습니다.
3. session이 있다면 로그인을 기존에 한 user이므로 session.getAttribute(SessionConst.LOGIN_MEMBER)를 실행하여 SessionDto에 정보를 넣어주는 역할을 하게 됩니다.
4. MVC에서 사용할 수 있도록 WebConfig에 등록해줍니다.
패키지와 WebConfig를 생성해줍니다.
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new ArgumentResolver());
}
}
- WebMvcConfigurer를 상속받고, addArugmentResolvers를 Override 하여 저희가 만든 ArgumentResolver를 추가해줍니다.
5. MemberController변경
@RestController
@RequiredArgsConstructor
@RequestMapping("/member")
public class MemberController {
private final MemberService memberService;
@PostMapping("/request/{teamId}")
public Long requestTeam(@PathVariable(name = "teamId")Long teamId,@LoginUser SessionDto sessionUser){
Long okId = memberService.requestTeam(teamId,sessionUser.getId());
return okId;
}
@GetMapping("/request")
public List<RequestTeamDto> requestList(@LoginUser SessionDto sessionUser){
return memberService.findRequestList(sessionUser.getId());
}
@DeleteMapping("/request/{teamId}")
public String deleteRequest(@PathVariable(name = "teamId") Long teamId,@LoginUser SessionDto sessionUser){
memberService.WithdrawalTeamRequest(sessionUser.getId(),teamId);
return "ok";
}
@DeleteMapping("/request")
public String leavingTeam(@LoginUser SessionDto sessionUser){
memberService.leavingTeam(sessionUser.getId());
return "ok";
}
}
6. Postman을 이용해서 테스트해보겠습니다.
회원 가입을 진행해줍니다.
로그인을 하기 전에는 Session이 없기 때문에 Cookies에 아무런 내용이 없습니다.
로그인 요청을 보낸 후 성공했습니다. 그리고 Session이 생성된 것을 알 수 있습니다.
ArgumentResolver가 잘 작동하는지 알아보기 위해서 Member가 팀 가입 신청한 리스트를 찾는 로직을 실행합니다. Team이 아직 생성되지 않아도 가능하므로 잘 작동한다면 [] 비어있는 List를 받으며
- Get localhost/member/request 요청 보냅니다.
- Team이 아직 생성되지 않아도 가능하므로 잘 작동한다면 [] 비어있는 List를 받습니다.
- 작동하지 않는다면 Member를 찾을 수 없는 오류를 터뜨릴 것입니다.
ArgumentResolver가 잘 작동하여 빈 List를 받은 것을 확인할 수 있습니다.
지금까지 Annotation을 활용한 ArgumentResolver를 만들어봤습니다. 저희는 로그인만 성공하면 Member에 관한 모든 로직을 사용할 수 있는 형태였습니다. 하지만 TeamFounder나 LeagueHost의 역할을 가진 다른 User는 사용하지 못하도록 Interceptor를 만들어보겠습니다. 감사합니다.
모든 코드는 아래 링크에서 확인 가능합니다.
https://github.com/rlaehdals/blogProject
'SpringBoot > spring 프로젝트 만들기' 카테고리의 다른 글
SpringBoot [스프링부트] 시작하기(9) Team 내부 로직 만들기 (0) | 2022.01.17 |
---|---|
SpringBoot [스프링부트] 시작하기(8) Interceptor 만들기 (0) | 2022.01.16 |
SpringBoot [스프링부트] 시작하기(6) MemberController 만들기 (0) | 2022.01.15 |
SpringBoot [스프링부트] 시작하기(5) Member 관련 완성하기 (0) | 2022.01.15 |
SpringBoot [스프링부트] 시작하기(4) RestController, RestControllerAdvice,ExceptionHanlder Restful API 예외 처리 (0) | 2022.01.14 |
댓글
이 글 공유하기
다른 글
-
SpringBoot [스프링부트] 시작하기(9) Team 내부 로직 만들기
SpringBoot [스프링부트] 시작하기(9) Team 내부 로직 만들기
2022.01.17 -
SpringBoot [스프링부트] 시작하기(8) Interceptor 만들기
SpringBoot [스프링부트] 시작하기(8) Interceptor 만들기
2022.01.16 -
SpringBoot [스프링부트] 시작하기(6) MemberController 만들기
SpringBoot [스프링부트] 시작하기(6) MemberController 만들기
2022.01.15 -
SpringBoot [스프링부트] 시작하기(5) Member 관련 완성하기
SpringBoot [스프링부트] 시작하기(5) Member 관련 완성하기
2022.01.15