오늘 할일

  • 장바구니 2단계 진행
    • ArgumentResolver, Interceptor 사용하여 인증 구현
    • 장바구니 담기 구현
  • 학습 테스트
    • Basic auth
    • Session
    • Token auth
    • Interceptor
    • ArgumentResolver

학습테스트 정리

1. View Controller

호출되자마자 즉시 뷰를 전달하는 ParameterizableViewController 를 정의하는 방법.
뷰를 생성할 때 추가적인 로직이 필요하지 않은 경우 Java Controller를 사용하지 않고 처리하는 방법.

WebMvcConfigurer를 구현하는 Configuration에서 addViewControllers() 에서 경로에 따라서 어느 뷰의 이름을 지정해준다.

@Configuration  
public class WebMvcConfiguration implements WebMvcConfigurer {

    @Override  
    public void addViewControllers(ViewControllerRegistry registry) {  
        registry.addViewController("/").setViewName("hello");  
    }
    ...
}

해당 URL에 @RequestMapping 로 매핑되어 있다면 뷰 컨트롤러는 해당 URL에 대해 핸들링할 수 없음. URL을 어노테이션으로 매핑하는 것은 엔드포인트 소유권을 강하게 표시하는 것이기 때문.

2. Interceptor

로깅, 인증 확인과 같은 코드의 반복을 줄이기 위해 사용한다.

Handler Mapping이 실행할 컨트롤러를 찾아주면, request를 처리하기 전에 DispatcherServlet이 Interceptor를 호출할 수 있다.

  • prehandle() – 실제 핸들러가 실행되기 전에 호출됨. HandlerMapping 이 적절한 핸들러 객체를 선택한 후에 실행됨.
  • postHandle() – 실제 핸들러가 실행된 후에 호출됨. 핸들러 실행이 끝난 후에 인터셉트함. HandlerAdapter 가 핸들러를 호출한 후, DispatcherServlet이 뷰를 렌더하기 전에 인터셉트함.
  • afterCompletion() – request가 끝나고 뷰가 생성된 후에 호출됨

HandlerInterceptorAdapter를 확장해서 사용한다.

public class LoginInterceptor extends HandlerInterceptorAdapter {  
@Override  
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {  
        String accessToken = request.getHeader("Authorization");  
        if (accessToken == null) {  
            throw new AuthorizationException();  
        }  

        return super.preHandle(request, response, handler);  
        }  
}

WebMvcConfigurer를 구현하는 Configuration에서 addInterceptors() 에 interceptor와 url을 설정한다.

@Configuration  
public class WebMvcConfiguration implements WebMvcConfigurer {
    ...
    @Override  
    public void addInterceptors(InterceptorRegistry registry) {  
        registry.addInterceptor(new LoginInterceptor())  
        .addPathPatterns("/admin/members");  
    }
    ...
}

3. ArgumentResolver

Spring MVC가 컨트롤러 메서드를 호출할 때, 요청 파라미터와 HTTP 헤더 등의 값을 해당 메서드의 매개변수에 바인딩하는 데 사용된다. 즉, 이 인터페이스를 구현한 객체는 컨트롤러 메서드에서 사용할 수 있는 객체를 생성하거나 변환하는 기능을 제공한다.

먼저 사용할 어노테이션을 정의해준다. 컨트롤러의 파라미터에 이 어노테이션을 붙이면 ArgumentResolver를 통해 완성된 객체를 파라미터를 전달받을 수 있을것이다.

@Target(ElementType.PARAMETER)  
@Retention(RetentionPolicy.RUNTIME)  
public @interface AuthenticationPrincipal {  
    boolean required() default true;  
}

HandlerMethodArgumentResolver 를 구현하는 ArgumentResolver를 생성한다. supportsParameter() 에서 어노테이션을 검사하여 resovleArgument() 를 실행할지 결정한다.

public class AuthenticationPrincipalArgumentResolver implements HandlerMethodArgumentResolver {  

    @Override  
    public boolean supportsParameter(MethodParameter parameter) {  
    return parameter.hasParameterAnnotation(AuthenticationPrincipal.class);  
    }  

    @Override  
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {  
    return new LoginMember(1L, "email", 120);  
    }  
}

WebMvcConfigurer를 구현하는 Configuration에서 addArgumentResoilvers() 에 사용할 ArgumentResolver를 등록한다. 지금은 직접 초기화해주었지만, 빈으로 등록해서 주입받아서 사용할 수 있다.

@Configuration  
public class WebMvcConfiguration implements WebMvcConfigurer {
    ...
    @Override  
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {  
        resolvers.add(new AuthenticationPrincipalArgumentResolver());  
    }
}

Controller에서 파라미터에 정의했던 어노테이션을 사용하여 완성된 객체를 파라미터로 전달받도록 할 수 있다.

@GetMapping("/members/me")  
public ResponseEntity<LoginMember> findMemberOfMine(@AuthenticationPrincipal LoginMember loginMember) {  
    return ResponseEntity.ok().body(loginMember);  
}

'회고 > 우아한테크코스' 카테고리의 다른 글

2023.05.04 일일 회고  (0) 2023.05.05
2023.05.03 일일 회고  (0) 2023.05.04
2023.04.25 일일 회고  (0) 2023.04.26
2023.04.24 일일 회고  (0) 2023.04.25
2023.04.20 일일 회고  (0) 2023.04.21

+ Recent posts