문제점
RestfulPatterns는 match() 시 자신의 Path와 HttpMethod에 해당하는 HTTP Request에 true를 반환해야 한다.
기존에는 RestfulPatterns 가 UriTemplate 을 사용하도록 개발했다.
public class RestfulPattern {
private final UriTemplate path;
private final Set<HttpMethod> methods;
private RestfulPattern(final UriTemplate path, final Set<HttpMethod> methods) {
this.path = path;
this.methods = methods;
}
...
}
하지만, 테스트 코드를 작성하는 과정에서 UriTemplate이 /**와 같은 와일드카드 경로를 제대로 처리하지 못한다는 사실을 발견했다.
예를 들어, /foo 경로를 /** 경로와 매칭시켜보니 false가 나오는 문제가 있었다.
RestfulPatterns는 기존의 InterceptorRegistry에서 Interceptor의 URI를 등록하는 동작과 거의 동일하게 동작해야 했지만, 와일드카드 경로 매칭이 제대로 이루어지지 않았다.
문제 해결 과정
이 문제를 해결하기 위해 기존의 MappedInterceptor가 경로 매칭을 어떻게 수행하는지 확인했다.
HandlerInterceptor의 구현체를 InterceptorRegistry에 등록할 때, 경로 패턴을 추가하면 해당 Interceptor는 MappedInterceptor로 변환된다.
MappedInterceptor는 요청 경로를 구분하여 동작하는 Interceptor로, 기본적으로 AntPathMatcher를 사용하여 경로 매칭을 처리한다.
public final class MappedInterceptor implements HandlerInterceptor {
private static final PathMatcher defaultPathMatcher = new AntPathMatcher();
...
private PathMatcher pathMatcher = defaultPathMatcher;
...
private final HandlerInterceptor interceptor;
...
}
Spring 의 MappedInterceptor는 AntPathMatcher를 기본으로 사용하고 있었다.
AntPathMatcher는 Spring에서 경로 패턴 매칭을 처리하는 클래스로, UriTemplate과 달리 와일드카드 패턴 등을 사용해 경로를 매칭할 수 있다는 점에서 차별화되었다.
RestInterceptor를 설계할 때의 철학 중 하나는 "기존의 Interceptor를 사용하는 방법과 거의 유사하게 사용할 수 있도록 하자"는 것이었다.
기존의 Interceptor와 사용법이 크게 다르면 사용자에게 불편함을 줄 수 있기 때문이다.
이에 따라, RestfulPattern이 MappedInterceptor와 동일하게 AntPathMatcher를 사용하도록 개선했다.
개선된 점
public class RestfulPattern {
private final String path;
private final Set<HttpMethod> methods;
private final AntPathMatcher pathMatcher = new AntPathMatcher();
...
public boolean matches(final HttpServletRequest request) {
return methods.contains(HttpMethod.valueOf(request.getMethod())) &&
pathMatcher.match(path, request.getRequestURI());
}
...
}
UriTemplate 대신 AntPathMatcher를 도입함으로써 두 가지 주요 개선이 이루어졌다:
- 와일드카드 기반 경로 매칭 가능: AntPathMatcher를 사용하여 /**와 같은 와일드카드 경로도 정확하게 매칭할 수 있게 되었다.
- 기존 Interceptor와의 일관성: MappedInterceptor와 동일한 PathMatcher를 도입함으로써 기존 Interceptor와의 동작 불일치 문제를 해결했다.
'Spring Boot' 카테고리의 다른 글
RestInterceptor 개발기 - build() 메서드 제거와 v1.0 릴리즈 (0) | 2024.12.23 |
---|---|
Spring 라이브러리 개발기 - RestInterceptor v0.1 (0) | 2024.11.29 |
Redis 캐싱만 적용하면 끝일까? - Resilience4j 를 통한 Circuit Breaker 적용 (7) | 2024.10.15 |
Spring Boot에서 Redis를 활용해 데이터 캐싱하기(feat. Look Aside) (1) | 2024.06.17 |
Interceptor를 활용한 JWT 토큰 검증 (1) | 2024.06.07 |