欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > springMVC是如何做url映射到controller的?

springMVC是如何做url映射到controller的?

2024/10/25 7:34:46 来源:https://blog.csdn.net/joshua1830/article/details/140647656  浏览:    关键词:springMVC是如何做url映射到controller的?

背景

最近要做一个URL到权限的控制,需要根据实际的URL匹配到配置文件,一般的url好处理,但是对于path parameter 的URL就需要做匹配了,所以研读了一下springmvc的源码,看看是如何做的

  • 入口 FrameworkServlet
    • .doPost(HttpServletRequest request, HttpServletResponse response)
  • DispatcherServlet
    • .doService
    • DispatcherServlet.doDispatch
    • HandlerExecutionChain mappedHandler =getHandler(processedRequest)
      这里有多个handlerMapping,实际用到的是RequestMappingHandlerMapping
this.handlerMappings ={ArrayList@14007} size =7
0={WebMvcEndpointHandlerMapping@13963}
1={ControllerEndpointHandlerMapping@14199}
2={RequestMappingHandlerMapping@9698}
3={BeanNameUrlHandlerMapping@14200}
4= {RouterFunctionMapping@14201}
5={SimpleUrlHandlerMapping@14202}
6={WelcomePageHandlerMapping@14203}
  • AbstractHandlerMethodMapping
    从这个mapping 中获取RequestMappingHandlerMapping
    • HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request)
	protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {List<Match> matches = new ArrayList<>();List<T> directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath);if (directPathMatches != null) {addMatchingMappings(directPathMatches, matches, request);}if (matches.isEmpty()) {// No choice but to go through all mappings...addMatchingMappings(this.mappingRegistry.getMappings().keySet(), matches, request);}

这段代码有意思,先去根据url 去map中找RequestMappingInfo (封装了URL匹配相关信息) ,然后去做URL匹配

    • MappingRegistry 保存了所有的配置
mappingLookup 保存了RequestMappingInfo 和 HandlerMethod 的映射
MultiValueMap<String, T> urlLookup 保存了路径和方法的映射
  • 所有的配置信息封装在 RequestMappingInfo
	public RequestMappingInfo getMatchingCondition(HttpServletRequest request) {RequestMethodsRequestCondition methods = this.methodsCondition.getMatchingCondition(request);if (methods == null) {return null;}ParamsRequestCondition params = this.paramsCondition.getMatchingCondition(request);if (params == null) {return null;}HeadersRequestCondition headers = this.headersCondition.getMatchingCondition(request);if (headers == null) {return null;}ConsumesRequestCondition consumes = this.consumesCondition.getMatchingCondition(request);if (consumes == null) {return null;}ProducesRequestCondition produces = this.producesCondition.getMatchingCondition(request);if (produces == null) {return null;}PatternsRequestCondition patterns = this.patternsCondition.getMatchingCondition(request);if (patterns == null) {return null;}RequestConditionHolder custom = this.customConditionHolder.getMatchingCondition(request);if (custom == null) {return null;}return new RequestMappingInfo(this.name, patterns,methods, params, headers, consumes, produces, custom.getCondition());}

找到PatternsRequestCondition ,用来做和url做模式匹配

  • PatternsRequestCondition
this.pathMatcher = pathMatcher != null ? pathMatcher : new AntPathMatcher();this.pathMatcher.match("/Task/GetTaskById/{taskid}", "/Task/GetTaskById/123")

这里实际上是spring 的AntPathMatcher 类,直接调用即可匹配带参数的URL

总结

springMVC 做URL匹配,实际上分两步,1,用url去map中找List directPathMatches
2, 遍历List directPathMatches,逐个做pathMatcher

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com