본문 바로가기
spring

Spring MVC의 PathPattern (AntPathMatcher, PathPatternParser)

by moonsiri 2024. 5. 8.
728x90
반응형

spring boot 버전을 2.3.2.RELEASE(spring 5)에서 3.2.5(spring 6)로 버전업 하면서 double slash(//)가 포함된 경로를 찾을 수 없는 이슈가 발생하였습니다. (사실 오랫동안 버전업을 안 해서 이제야 발견한 거지만...) 찾아보니 spring-webmvc 5.2.x 버전에서 5.3.x로 넘어가면서 현재 요청 경로를 가져오는 로직이 변경되었습니다.
 
Spring 5.2 버전에서는 현재 요청 경로를 가져와야 할때 다음과 같은 방법으로 직접 가져왔습니다.

// https://github.com/spring-projects/spring-framework/blob/5.2.x/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);

Spring 5.3 버전에서는 새로운 기능으로 initLookupPath 메서드가 추가되어 다음과 같은 방식으로 현재 요청 경로를 가져옵니다.

// https://github.com/spring-projects/spring-framework/blob/5.3.x/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java
String lookupPath = initLookupPath(request);

// https://github.com/spring-projects/spring-framework/blob/5.3.x/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMapping.java
/**
 * Initialize the path to use for request mapping.
 * <p>When parsed patterns are {@link #usesPathPatterns() enabled} a parsed
 * {@code RequestPath} is expected to have been
 * {@link ServletRequestPathUtils#parseAndCache(HttpServletRequest) parsed}
 * externally by the {@link org.springframework.web.servlet.DispatcherServlet}
 * or {@link org.springframework.web.filter.ServletRequestPathFilter}.
 * <p>Otherwise for String pattern matching via {@code PathMatcher} the
 * path is {@link UrlPathHelper#resolveAndCacheLookupPath resolved} by this
 * method.
 * @since 5.3
 */
protected String initLookupPath(HttpServletRequest request) {
	if (usesPathPatterns()) {
		request.removeAttribute(UrlPathHelper.PATH_ATTRIBUTE);
		RequestPath requestPath = ServletRequestPathUtils.getParsedRequestPath(request);
		String lookupPath = requestPath.pathWithinApplication().value();
		return UrlPathHelper.defaultInstance.removeSemicolonContent(lookupPath);
	}
	else {
		return getUrlPathHelper().resolveAndCacheLookupPath(request);
	}
}

PathPatternParser를 사용하는 경우에는 request에서 URL 경로를 가져와서 분석한 후 애플리케이션 내부에서의 경로만 추출하여 세미콜론을 제거하고 결과를 리턴합니다. 사용하지 않은 경우에는 기존의 UrlPathHelper를 사용하여 요청의 경로를 해석하고 캐시합니다.
 
이전에는 Spring MVC가 URL 패턴을 매칭할 때 AntPathMatcher를 사용했고, 그에 따라 URL을 일치시킬때 몇 가지 규칙을 따랐습니다. 그러나 SpringBoot 2.6 버전부터는 URL 패턴 매칭 기본 전략이 AntPathMatcher에서 PathPatternParser로 변경되었습니다. PathPatternParser는 경로 매칭 시 좀 더 엄격한 규칙을 따르고 보다 표준화된 URL 매칭을 지원합니다.
 
 


 
 

AntPathMatcher

  • 기존 Spring에서 많이 사용되었던 방식
  • 경로 매칭을 위해 Ant 스타일의 패턴을 사용
  • '*'은 임의의 문자열을 의미하고, '**'는 임의의 경로를 의미
    • "/path/**"는 "/path/abc", "/path/abc/def" 등과 일치
AntPathMatcher pathMatcher = new AntPathMatcher();
System.out.println(pathMatcher.match("/path/**", "/path/abc")); // true
System.out.println(pathMatcher.match("/path/**", "/path/abc/def")); // true

 

PathPatternParser

  • Srping 5 부터 도입된 새로운 URL 매칭 방식
  • 경로 매칭을 위해 경로 패턴을 사용하며, 표준화된 문법을 따름
  • '{'와 '}'를 사용하여 변수를 나타내며, '**'는 임의의 경로를 의미
    • "/path/{var}"는 "/path/abc", "/path/123" 등과 일치하지만 "/path/abc/def"와는 일치하지 않음
PathPatternParser patternParser = new PathPatternParser();
PathPattern pathPattern = patternParser.parse("/path/{var}");
System.out.println(pathPattern.matches("/path/abc")); // true
System.out.println(pathPattern.matches("/path/abc/def")); // false

 

정리

AntPathMatcher는 유연성이 있고 간단한 URL 매칭에 적합합니다. 반면에 PathPatternParser는 더 엄격하고 표준화된 URL 패턴을 사용하여 보다 안전하고 예측 가능한 URL 매칭을 제공합니다.
신규 프로젝트나 업그레이드하는 경우에는 PathPatternParser를 사용하는 것이 권장됩니다.
 
만약 기본전략을 기존의 AntPathMatcher를 사용하도록 구성하려면 URL 경로 매칭을 구성하는 configurePathMatch 메서드에서 setPatternParser(null)을 호출하여 기본적으로 사용되는 PathPatternParser를 비활성화하면 됩니다.

@EnableWebMvc
@Configuration
public class MvcConfiguration implements WebMvcConfigurer {

	// ...

	@Override
	public void configurePathMatch(PathMatchConfigurer configurer) {
		configurer.setPatternParser(null);
	}
}

 
 
[Reference]
https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-servlet/handlermapping-path.html
https://velog.io/@this-is-spear/PathPatternParser-%EB%8F%99%EC%9E%91-%EC%9D%B4%ED%95%B4

728x90
반응형

댓글