公司支付网站建设费进什么费用,中国建设银行征信中心网站,u钙网在线制作logo,搜索引擎优化seo优惠注解RequestMapping中的URI路径最前面到底需不需要加斜线?
您有没有这样的困惑#xff1a;在协同开发过程中#xff0c;使用RequestMapping#xff0c;或者是GetMapping#xff0c;或者是PostMapping这类注解时#xff0c;有的程序员加了斜线#xff0c;有的程序员没有…注解RequestMapping中的URI路径最前面到底需不需要加斜线?
您有没有这样的困惑在协同开发过程中使用RequestMapping或者是GetMapping或者是PostMapping这类注解时有的程序员加了斜线有的程序员没有加斜线实际好像都能访问到那么到底需不需要加呢
举例 以上路径写法都是可以访问的 加不加都可以访问从这一点可以推断出结论RequestMapping最前面的斜线可加可不加这里只是说最前面如果是/a/b/c中间的斜线分隔符是一定要加的
所谓知其然一定要知其所以然为什么可以加也可以不加呢Spring框架一定是做了什么处理那么框架是怎么处理的呢
这里就用这个TestController测试控制器路径/test/testPath来扒一扒源码一窥裙底满足一下好奇心
思路我们可以访问/test/testPath这个路径服务端根据这个路径提供相应的服务那么第一服务端已经准备好了这个路径等着客户端来调用第二当客户端访问这个路径时服务端要去找到这个路径对应的服务。
第一web容器启动的时候org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping会扫描Controller注解找到所有的Handler这里把处理器就称为Handler等会儿好理解类拿到所有的Handler类之后会遍历这些Handler类并且遍历这个Handler类中所有带RequestMapping的方法同时把类和方法的路径拼起来框架叫做combine联结在一起注意Handler类可以不要RequestMapping在这个过程中会判断路径的最前面是否有斜线/如果没有会拼一个斜线/所以这就是为什么不加可以 以下简单的写出相关的类和方法简单的说明以下调用时序当然不够规范如果要来真的应该画个时序图 扫描Handler调用时序
1,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping afterPropertiesSet2,org.springframework.web.servlet.handler.AbstractHandlerMethodMapping afterPropertiesSet initHandlerMethods detectHandlerMethods(到这个地方循环发现所有Handler以下为找到具体的URL并处理为规范的URL) getMappingForMethod3,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping getMappingForMethod createRequestMappingInfo combine4,org.springframework.web.servlet.mvc.method.RequestMappingInfo RequestMappingInfo.Builder build PatternsRequestCondition5,org.springframework.web.servlet.mvc.condition.PatternsRequestCondition prependLeadingSlash
接下来调皮的人来了不加斜线框架会帮我拼一个斜线相当于加了斜线那么我加很多很多斜线呢比如说斜线斜线斜线testPath这里打斜线符号会被转义所以用中文这样可以吗
像上图这样也是可以访问的这是为什么呢要解答这个问题就要看客户端访问服务端时服务端是怎么找相应的Handler的
第二客户端注意框架会将客户端的URI处理成标准格式即/test/testPath不管是浏览器地址栏上的URI还是使用HttpClient刻意加上很多斜线最终服务端要处理的URI都会是/test/testPath在访问服务端时服务端的org.springframework.web.servlet.DispatcherServlet会拿到本次请求的request根据请求的路径找到已经准备好的Handler而在找Handler的时候会匹配路径匹配路径的时候会把路径按斜线分割后匹配///test///testPath和/test/testPath按斜线分割后都是{“test”,“testPath”}所以你加了多个斜线没关系效果一样注Spring框架是用的java.util.StringTokenizer工具类来分割URI的StringTokenizer stringTokenizer new StringTokenizer(//testtestPath, “/”)
框架处理客户端的URI
框架匹配客户端和服务端的URI
分割后匹配URI
查找Handler调用时序
查找Handler调用时序
1,org.springframework.web.servlet.DispatcherServlet doService doDispatch getHandler2,org.springframework.web.servlet.HandlerMapping getHandler3,org.springframework.web.servlet.handler.AbstractHandlerMapping getHandler getHandlerInternal(到这个地方已经发现所有的Handler)4,org.springframework.web.servlet.handler.AbstractHandlerMethodMapping getHandlerInternal lookupHandlerMethod addMatchingMappings getMatchingMapping5,org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping getMatchingMapping getMatchingCondition6,org.springframework.web.servlet.mvc.method.RequestMappingInfo getMatchingCondition getMatchingCondition7,org.springframework.web.servlet.mvc.condition.PatternsRequestCondition getMatchingCondition getMatchingPatterns getMatchingPattern this.pathMatcher.match8,org.springframework.util.AntPathMatcher match doMatch tokenizePattern(该部分为工具类只用于处理并规范URL)
结论
1RequestMapping最前面可以加斜线比如RequestMapping(/testPath)
2RequestMapping最前面可以不加斜线比如RequestMapping(“testPath”)
3RequestMapping最前面可以加很多斜线比如RequestMapping(///testPath)
建议规范一点加上一个斜线