spring-projects / spring-framework

Spring Framework
https://spring.io/projects/spring-framework
Apache License 2.0
56.14k stars 37.95k forks source link

RequestPredicates fail with UnsupportedOperationException with a custom servlet path #33251

Closed xgwcy closed 1 month ago

xgwcy commented 1 month ago

Define a RouterFunction:

@Bean
  RouterFunction<ServerResponse> nest() {
    return route()
            .path("/persons", builder -> builder
                .GET("/{id}", accept(MediaType.TEXT_HTML), request -> ServerResponse.ok().body("query person"))
            )
            .build();
  }

Configure the following servlet path in application.yml

spring:
  mvc:
    servlet:
      path: /api

Access the GET /api/persons/666 interface,The console throws the following error.

java.lang.UnsupportedOperationException: null
    at org.springframework.web.util.ServletRequestPathUtils$ServletRequestPath.modifyContextPath(ServletRequestPathUtils.java:221) ~[spring-web-5.3.31.jar:5.3.31]
    at org.springframework.web.servlet.function.RequestPredicates$SubPathServerRequestWrapper.requestPath(RequestPredicates.java:944) ~[spring-webmvc-5.3.31.jar:5.3.31]
    at org.springframework.web.servlet.function.RequestPredicates$SubPathServerRequestWrapper.<init>(RequestPredicates.java:933) ~[spring-webmvc-5.3.31.jar:5.3.31]
    at org.springframework.web.servlet.function.RequestPredicates$PathPatternPredicate.lambda$nest$0(RequestPredicates.java:519) ~[spring-webmvc-5.3.31.jar:5.3.31]
    at java.base/java.util.Optional.map(Optional.java:260) ~[na:na]
    at org.springframework.web.servlet.function.RequestPredicates$PathPatternPredicate.nest(RequestPredicates.java:519) ~[spring-webmvc-5.3.31.jar:5.3.31]
    at org.springframework.web.servlet.function.RouterFunctions$DefaultNestedRouterFunction.route(RouterFunctions.java:1027) ~[spring-webmvc-5.3.31.jar:5.3.31]
    at org.springframework.web.servlet.function.RouterFunctionBuilder$BuiltRouterFunction.route(RouterFunctionBuilder.java:392) ~[spring-webmvc-5.3.31.jar:5.3.31]
    at org.springframework.web.servlet.function.RouterFunctions$DifferentComposedRouterFunction.route(RouterFunctions.java:928) ~[spring-webmvc-5.3.31.jar:5.3.31]
    at org.springframework.web.servlet.function.support.RouterFunctionMapping.getHandlerInternal(RouterFunctionMapping.java:220) ~[spring-webmvc-5.3.31.jar:5.3.31]
    at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:498) ~[spring-webmvc-5.3.31.jar:5.3.31]
    at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1266) ~[spring-webmvc-5.3.31.jar:5.3.31]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1048) ~[spring-webmvc-5.3.31.jar:5.3.31]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:965) ~[spring-webmvc-5.3.31.jar:5.3.31]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.31.jar:5.3.31]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.31.jar:5.3.31]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:529) ~[tomcat-embed-core-9.0.83.jar:4.0.FR]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.31.jar:5.3.31]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:623) ~[tomcat-embed-core-9.0.83.jar:4.0.FR]

version: Spring5.x and Spring6.x

bclozel commented 1 month ago

@xgwcy we're looking into this issue. In the meantime, you can consider the following as a replacement: server.servlet.context-path=/api.