Interceptor 에서 @Value 가 null 이다?

인터셉터나 필터에서 프로퍼티에 있는 값을 가져와서 사용할 경우가 종종 있습니다.

예시로 사용할 인터셉터를 하나 만들어보죠.

인터셉터에 대한 개념이 있다고 가정하고 진행하겠습니다.

import static org.springframework.http.HttpStatus.UNAUTHORIZED;

@Slf4j
public class ApiKeyInterceptor implements HandlerInterceptor {

    @Value("${api-key}")
    private String apiKey;

    private static final String HEADER_NAME = "api-key";

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.debug("VOD 인증 체크 인터셉터 실행 {}", request.getRequestURI());

        String value = request.getHeader(HEADER_NAME);
        if (!apiKey.equals(value)) {
            log.debug("VOD 인증 체크 api-key 필요");
            sendErrorResponse(response);
            return false;
        }
        return true;
    }

    private void sendErrorResponse(HttpServletResponse response) throws IOException {
        response.setContentType("application/json");
        response.setCharacterEncoding("utf-8");
        response.setStatus(UNAUTHORIZED.value());
        ApiResponse<Object> apiResponse = ApiResponse.of(UNAUTHORIZED, "인증키값을 확인해주세요.", null);
        String result = objectMapper.writeValueAsString(apiResponse);
        response.getWriter().write(result);
    }

}

위 코드에 대해서 간단히 설명하겠습니다.

클라이언트에서 요청을 보낼 때 api-key 값을 같이 보내줘서 해당 값이 프로퍼티에 적힌 api-key 의 값과 같다면 통과시키는 인터셉터입니다.

만약 키 값이 같지 않다면 401 상태코드와 “인증키값을 확인해주세요.” 란 메시지를 JSON 형태로 반환할 겁니다.

그리고 만든 인터셉터를 사용하기 위해서 등록을 해줍시다.

@Configuration
public class WebConfiguration implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new ApiKeyInterceptor())
                .addPathPatterns("/vod/add", "/vod/edit", "/vod/remove");
    }

}

이제 요청을 보내서 디버깅을 해볼까요?

Untitled

인터셉터가 등록됐고 동작하긴 하는데 NPE 이 발생합니다.

프로퍼티에 있는 값을 읽어오지 못했다는 뜻입니다. @Value가 작동하지 않아서 apiKey 필드값에 null 이 들어가고 null에다가 equals() 를 실행하니까 NPE가 발생하죠.

이렇게 @Value만 사용한다고 프로퍼티의 값을 가져올 수 없습니다.