https://sundaland.tistory.com/375
[ ▶ Path Matching ]
Path Matching은 Spring MVC에서 클라이언트 요청의 URL path를 기반으로 적절한 컨트롤러와 매핑하는 과정이다. Spring MVC는 URL 경로와 컨트롤러를 매핑하여 클라이언트 요청을 처리하는데, 이 과정에서 path matching에 다양한 옵션을 제공할 수 있다. 이러한 매칭 동작을 세부적으로 제어하기 위해 Spring MVC에서는 PathMatchConfigurer를 사용하여 매칭 방식을 커스터마이징할 수 있다.
[ ▷ PathMatchConfigurer란? ]
PathMatchConfigurer는 URL 경로와 컨트롤러 핸들러를 매핑할 때 경로를 처리하는 방법을 설정하는 데 사용되는 클래스이다. 이를 통해 경로 매칭의 동작 방식을 세부적으로 제어할 수 있으며, 기본 경로에 대한 전역적인 설정, 경로 패턴 처리, 경로 접두어 추가 등을 정의할 수 있다.
[ ▷ Path Matching 설정의 예 ]
아래의 예시는 Spring MVC에서 특정 애노테이션이 적용된 컨트롤러 클래스에만 특정 경로 접두어를 자동으로 추가하는 설정을 보여다.
▼ Path Prefix 추가하는 예시
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
// @RestController 애노테이션이 붙은 클래스에 자동으로 "/api" 경로 접두어를 추가
configurer.addPathPrefix("/api", HandlerTypePredicate.forAnnotation(RestController.class));
}
private PathPatternParser patternParser() {
// 이 메서드에서 추가적인 패턴 파서 설정이 가능
return new PathPatternParser();
}
}
- @Configuration: 이 클래스는 Spring의 설정 클래스임을 나타낸다. 여기서 Spring MVC의 설정을 커스터마이징한다.
- @EnableWebMvc: 이 애노테이션은 Spring MVC를 활성화하고 기본 설정을 로드한다. 이를 통해 커스터마이징할 수 있는 설정 지점을 제공한다.
- configurePathMatch(PathMatchConfigurer configurer): 이 메서드를 오버라이드하여 PathMatchConfigurer를 사용하여 경로 매칭 동작을 커스터마이징할 수 있다.
- addPathPrefix("/api", HandlerTypePredicate.forAnnotation(RestController.class)): 이 설정은 @RestController 애노테이션이 붙은 모든 컨트롤러 클래스에 대해 경로의 접두어로 /api를 자동으로 추가한다
- 예를 들어, @RestController가 적용된 컨트롤러에서 /users라는 경로를 매핑한 경우, 실제로 클라이언트가 접근해야 하는 경로는 /api/users가 된다.
- 즉, /api 접두어가 자동으로 추가됨으로써 REST API 엔드포인트를 일관성 있게 관리할 수 있다.
- PathPatternParser: 경로 패턴을 분석하고 해석하는 데 사용되는 파서이다. PathPatternParser는 Spring 5에서 도입된 새로운 경로 매칭 방식으로, 성능이 더 우수하고 더 복잡한 경로 매칭을 처리할 수 있다. 예를 들어, 경로 변수를 처리하거나 와일드카드 경로 매칭을 수행할 수 있다. patternParser() 메서드에서 이를 추가적으로 설정할 수 있지만, 이 예시에서는 구현 부분이 생략되었다.
[ ▷ PathMatchConfigurer의 유용한 기능들 ]
- setUseSuffixPatternMatch(boolean): 이 옵션은 경로에서 파일 확장자(예: .json, .xml)를 허용할지 여부를 설정한다.기본적으로 Spring MVC는 URL 경로에서 파일 확장자를 허용하여 /users.json과 같은 경로를 처리할 수 있도록 한다. 하지만 보안상 문제나 의도치 않은 매칭을 방지하고자 확장자 매칭을 비활성화할 수 있다.
- setUseTrailingSlashMatch(boolean): 경로에서 마지막에 오는 슬래시(/)를 허용할지 여부를 설정한다. 예를 들어, /users와 /users/를 동일하게 처리할지 여부를 설정할 수 있다.
- addPathPrefix(String prefix, Predicate<Class<?>> predicate): 특정 조건을 만족하는 클래스에 대해 경로 접두어를 추가할 수 있다. 위 예시에서는 @RestController가 적용된 클래스에 /api 접두어를 추가했지만, 다른 조건(Predicate)을 사용하여 추가적인 맞춤 설정을 할 수도 있다.
[ ▷ 경로 매칭 시 고려 사항 ]
- Restful API 설계: 위의 addPathPrefix("/api", ...) 설정은 REST API 설계에서 흔히 사용되는 패턴이다. 모든 REST API 경로에 공통된 접두어 /api를 추가함으로써 클라이언트가 쉽게 API와 다른 웹 애플리케이션 경로를 구분할 수 있게 된다.
- 애노테이션 기반 핸들러 선택: HandlerTypePredicate.forAnnotation(RestController.class)는 @RestController 애노테이션이 있는 클래스만 선택하여 /api 접두어를 추가하도록 설정하는 데 사용된다. 이와 같은 방식으로 다른 애노테이션(@Controller, @Service 등)을 기준으로 조건을 설정할 수도 있다.
[ ▷ PathPatternParser와 AntPathMatcher 비교 ]
Spring MVC는 기본적으로 AntPathMatcher를 사용하여 경로 매칭을 처리하지만, Spring 5부터는 PathPatternParser라는 새로운 경로 매칭 파서를 사용할 수 있다.
- AntPathMatcher: 기존의 경로 매칭 방식으로, 간단한 와일드카드 패턴(예: *, **)을 지원하며, 널리 사용된다. 그러나 성능상의 한계와 복잡한 매칭에서는 유연성이 떨어질 수 있다.
- PathPatternParser: Spring 5에서 새롭게 도입된 경로 매칭 방식으로, 더 나은 성능과 복잡한 경로 매칭에 대한 강력한 지원을 제공한다. 특히 대규모 애플리케이션이나 경로 패턴이 복잡한 경우 더 적합하다.
[ ▷ 요약 ]
- PathMatchConfigurer는 Spring MVC에서 URL 경로와 핸들러 매핑을 더 유연하게 제어할 수 있도록 해준다.
- addPathPrefix()를 사용하면 특정 애노테이션이 적용된 컨트롤러에 대해 경로 접두어를 자동으로 추가할 수 있어, RESTful API 설계 시 일관성을 유지할 수 있다.
- PathPatternParser는 더 복잡한 경로 매칭을 필요로 하거나 성능을 최적화하고 싶은 경우 사용할 수 있는 강력한 경로 매칭 파서이다.
패스 매칭(Path Matching)을 세부적으로 설정하는 것은 Spring MVC에서 URL 경로를 처리하는 데 있어 매우 중요한 이점들을 제공한다. 이러한 세부적인 설정은 애플리케이션의 구조와 경로 관리에 유연성을 부여하고, 성능을 최적화하며, 유지보수성을 높일 수 있는 여러 장점을 가지고 있다.
△ 경로 관리의 일관성과 단순성
세부적인 경로 매칭 설정을 통해 애플리케이션의 URL 구조를 더 일관성 있게 설계할 수 있다. 예를 들어, addPathPrefix()와 같은 기능을 사용하여 특정 컨트롤러에 대해 공통된 접두어를 추가할 수 있다.
- 예시: @RestController가 적용된 모든 클래스에 /api라는 접두어를 자동으로 추가하면, REST API 경로를 일관되게 관리할 수 있다. 이렇게 하면 모든 API 경로가 /api/users, /api/products 등으로 통일되며, 클라이언트가 접근할 때 경로 구조가 더 명확해진다.
이를 통해 URL 설계가 깔끔해지고, 클라이언트가 API와 일반 웹 페이지를 구분하는 데 도움을 줄 수 있다.
△ 유연한 경로 설계
Spring MVC에서 제공하는 세부적인 패스 매칭 옵션을 활용하면 애플리케이션의 요구에 맞춰 경로 설계를 유연하게 처리할 수 있다. 경로에 슬래시(/)를 허용하거나 확장자 매칭을 사용할지 여부를 결정하는 등의 설정을 통해, 경로 매칭을 보다 세밀하게 제어할 수 있다.
- Trailing Slash 처리: /users와 /users/를 동일한 경로로 처리할지, 아니면 다른 경로로 처리할지를 제어할 수 있다. 이를 통해 클라이언트가 슬래시를 붙이거나 붙이지 않아도 일관된 응답을 받을 수 있다.
- 확장자 매칭: URL에 확장자를 허용할지 설정할 수 있습니다. 예를 들어, /users.json 또는 /users.xml과 같은 경로를 허용하여 다양한 데이터 형식에 대한 요청을 처리할 수 있다.
△ REST API 설계의 유연성
REST API를 설계할 때 경로 매칭을 세부적으로 제어하면, API 버전 관리나 다양한 API 경로를 더 쉽게 처리할 수 있다.
- 버전 관리: 특정 API 경로에 버전 정보를 포함시키고 싶을 때, addPathPrefix()와 같은 기능을 사용하여 /v1/api, /v2/api와 같은 경로를 쉽게 관리할 수 있다. 이렇게 하면 API 버전별로 컨트롤러를 분리하고 경로를 제어할 수 있어 클라이언트가 버전에 맞는 API를 호출할 수 있다.
△ 경로 충돌 방지
경로 매칭을 세부적으로 관리하면, 서로 다른 컨트롤러 또는 핸들러가 동일한 URL 경로를 처리할 때 발생할 수 있는 경로 충돌을 방지할 수 있다. 예를 들어, 특정 애노테이션이 적용된 컨트롤러에만 접두어를 추가하거나 경로 패턴을 세밀하게 설정하여 이러한 충돌을 미리 방지할 수 있다.
- 예시: @RestController에 /api 접두어를 추가하면, 동일한 경로가 일반 웹 페이지를 처리하는 @Controller와 충돌하지 않도록 설계할 수 있다.
△ 성능 최적화
Spring 5에서 도입된 PathPatternParser와 같은 새로운 경로 매칭 방식을 사용하면, 기존의 AntPathMatcher보다 더 나은 성능을 얻을 수 있다. PathPatternParser는 경로 매칭을 더 빠르게 처리할 수 있어 대규모 애플리케이션에서도 성능 저하 없이 경로 매칭을 효율적으로 처리할 수 있다.
- 정적 리소스와 동적 리소스 분리: 경로 매칭을 세부적으로 제어하면, 정적 리소스(CSS, 이미지, JavaScript 파일 등)와 동적 리소스(API 요청 등)를 명확히 분리하여 서버 자원을 효율적으로 사용할 수 있다. 이를 통해 경로에 따라 처리할 리소스를 최적화할 수 있다.
△ 보안 강화
경로 매칭을 세부적으로 제어하면 보안 측면에서도 장점을 얻을 수 있다. 예를 들어, 경로 확장자 매칭을 비활성화하여 파일 확장자를 통한 경로 공격을 방지할 수 있다.
- 확장자 비허용: .html, .jsp, .exe와 같은 파일 확장자를 URL 경로에서 허용하지 않도록 설정하여, 클라이언트가 특정 파일에 직접 접근하는 것을 방지할 수 있다.
△ 정적 자원 및 동적 자원 처리의 분리
PathMatchConfigurer를 사용하면 정적 리소스와 동적 요청을 명확하게 분리하여 처리할 수 있다. 예를 들어, /static/ 또는 /resources/와 같은 경로는 정적 리소스를 처리하고, 나머지는 동적 요청을 처리하도록 경로 패턴을 구성할 수 있다.
- 예시: /static/**는 CSS, 이미지 파일 등을 처리하도록 디폴트 서블릿으로 넘기고, 나머지 요청은 DispatcherServlet을 통해 동적 처리가 되도록 설정할 수 있다. 이를 통해 정적 리소스와 동적 컨트롤러 요청 간의 충돌을 방지하고, 더 효율적으로 리소스를 관리할 수 있다.
경로 매칭을 세부적으로 설정하면 애플리케이션의 경로 구조를 더욱 유연하고 일관성 있게 관리할 수 있으며, 경로 충돌 방지, 성능 최적화, 보안 강화 등 다양한 이점을 얻을 수 있다. 특히 RESTful API 설계 시 버전 관리나 경로 패턴 처리의 유연성을 통해 더 확장 가능하고 유지보수하기 쉬운 애플리케이션을 만들 수 있다. Path Matching은 단순한 설정처럼 보이지만, 이를 효과적으로 활용하면 애플리케이션의 구조와 성능을 크게 개선할 수 있다.
'Web on Servlet Stack' 카테고리의 다른 글
Annotated Controllers[1] (1) | 2024.10.16 |
---|---|
View Resolvers (0) | 2024.10.15 |
View Controllers (0) | 2024.10.15 |
Content Types (1) | 2024.10.15 |
Validation (0) | 2024.10.15 |