如何获取不含路径变量的Request URI?
如何获取Spring MVC中不含路径变量的请求路径?
在Spring MVC中,request.getRequestURI()会返回包含路径变量的完整URI。比如定义了如下接口:
@RequestMapping(value = "/getUser/{username}", method = RequestMethod.GET) public ResponseEntity<UserDTO> getUser(@PathVariable String username)
当请求localhost:8080/user/getUser/tommy时,request.getRequestURI()返回user/getUser/tommy,但需要得到user/getUser/或user/getUser这样不含路径变量的路径,可通过以下几种方法实现:
解决方案
方法1:通过HandlerMapping获取匹配的路径模板
在请求处理方法中,直接从请求属性中获取Spring匹配到的原始路径模板,替换掉变量占位符即可:
import org.springframework.web.servlet.HandlerMapping; import javax.servlet.http.HttpServletRequest; @RequestMapping(value = "/getUser/{username}", method = RequestMethod.GET) public ResponseEntity<UserDTO> getUser(@PathVariable String username, HttpServletRequest request) { // 获取@RequestMapping中定义的原始路径模板 String pathTemplate = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE); // 结合应用上下文路径,替换路径变量占位符 String contextPath = request.getContextPath(); String targetPath = contextPath + pathTemplate.replace("{username}", ""); // 可选:去掉末尾的斜杠 targetPath = targetPath.replaceAll("/$", ""); // 后续业务逻辑... return ResponseEntity.ok(new UserDTO()); }
HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE会返回/getUser/{username},替换占位符后就能得到不含变量的基础路径,适配大部分场景。
方法2:全局场景下通过RequestMappingHandlerMapping匹配
如果需要在拦截器、全局过滤器中处理,可以通过Spring的RequestMappingHandlerMapping获取所有注册的接口路径,再与当前请求URI匹配:
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import org.springframework.web.util.pattern.PathPattern; import javax.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired; // 注入RequestMappingHandlerMapping @Autowired private RequestMappingHandlerMapping handlerMapping; public String getPathWithoutVariables(HttpServletRequest request) { String requestUri = request.getRequestURI(); // 遍历所有注册的接口路径模板 for (var entry : handlerMapping.getHandlerMethods().entrySet()) { var mappingInfo = entry.getKey(); for (PathPattern pattern : mappingInfo.getPathPatternsCondition().getPatterns()) { if (pattern.matches(requestUri)) { // 匹配成功后,移除所有路径变量占位符 String templatePath = pattern.getPatternString(); String targetPath = templatePath.replaceAll("\\{[^}]+\\}", ""); // 拼接上下文路径并处理末尾斜杠 targetPath = request.getContextPath() + targetPath; return targetPath.replaceAll("/$", ""); } } } return null; }
这种方法适合需要统一处理所有请求路径的场景,能精准匹配到对应的原始路径模板。
方法3:字符串分割处理(仅适合简单场景)
如果你的路径变量固定在最后一段,可以用字符串分割的方式快速处理:
String requestUri = request.getRequestURI(); // 截取到倒数第二个斜杠的位置,去掉最后一段路径变量 int lastSlashIndex = requestUri.lastIndexOf("/"); String targetPath = requestUri.substring(0, lastSlashIndex);
注意:这种方法局限性很强,若路径中间包含变量会导致结果错误,仅适合简单的单变量末尾场景。
内容的提问来源于stack exchange,提问作者kernel
相关产品推荐
相关产品推荐

