浅谈SpringWeb请求解析过程
字数 2804 2025-08-06 12:20:48

Spring Web请求解析过程详解

0x00 前言

Spring MVC框架中,DispatcherServlet是前端控制器设计模式的实现,作为Spring Web MVC的集中访问点,负责职责的分派。主要职责包括:

  1. 文件上传解析(通过MultipartResolve处理multipart请求)
  2. 通过HandlerMapping将请求映射到处理器(返回HandlerExecutionChain,包含处理器和多个拦截器)
  3. 通过HandlerAdapter支持多种类型的处理器
  4. 通过ViewReslver解析逻辑视图名到具体视图实现
  5. 本地化解析
  6. 渲染具体视图
  7. 异常处理(通过HandlerExecutionResolver

0x01 Spring Web解析过程

以spring-webmvc 5.3.9为例,请求处理流程:

  1. Servlet容器调用DispatcherServletservice方法(实现在父类FrameworkServlet中)
  2. 获取请求类型,除PATCH方法外都通过HttpServletservice方法处理
  3. 根据请求方法调用processRequest方法(如GET请求调用doGet
  4. 执行doService方法后调用doDispatch处理请求

doDispatch方法处理流程:

  1. 对multipart请求进行处理
  2. 获取对应的mappedHandler(通过getHandler方法)
  3. getHandler方法按顺序循环调用HandlerMappinggetHandler方法

常见的HandlerMapping实现:

  • RequestMappingHandlerMapping:处理注解配置的路由

getHandlerInternal方法:

  1. 从request对象获取请求path
  2. 根据path找到handlerMethod
  3. 通过UrlPathHelper类进行路径处理

lookupHandlerMethod方法:

  1. 直接根据路径获取对应的Mapping
  2. 获取不到时调用addMatchingMappings遍历所有RequestMappingInfo对象进行匹配

getMatchingCondition方法(版本差异):

  • 高版本使用PathPattern进行URL匹配
  • 2.6之前使用AntPathMatcher进行字符串模式匹配

0x02 工具类

2.1 路径处理帮助类UrlPathHelper

UrlPathHelper是Spring的帮助类,用于解析请求中的路径,主要方法:

  1. resolveAndCacheLookupPath方法
  2. getPathWithinApplication方法:
    • 获取ContextPath并进行解码操作
    • 获取requestUri(通过request.getRequestURI()
    • 对URI进行解码、移除分号内容并清理斜线等处理

decodeAndCleanUriString方法处理:

  1. removeSemicolonContent:根据设置删除分号或Jsessionid
  2. decodeRequestString:解码操作
  3. getSanitizedPath:将//替换为/

getRemainingPath方法:将mapping字符与requestUri字符串匹配,忽略分号部分

alwaysUseFullPath属性:

  • 决定是否经过getPathWithinServletMapping方法处理
  • Spring Boot ≤2.3.0.RELEASE默认为false
  • Spring Boot ≥2.3.1.RELEASE默认为true

getPathWithinServletMapping方法:

  1. 调用getPathWithinApplication处理
  2. 获取ServletPath(通过request.getServletPath
  3. 对URI标准化处理(解码、处理跨目录等)

0x03 关键属性

3.1 SuffixPatternMatch/TrailingSlashMatch

SuffixPatternMatch(后缀匹配模式):

  • .xxx结尾的方式进行匹配
  • /hello/hello.do匹配结果相同
  • 5.3后useSuffixPatternMatch默认值由true变为false

TrailingSlashMatch(尾部斜杠匹配):

  • 为true时应用尾部/匹配
  • /hello/hello/匹配结果相同

3.2 alwaysUseFullPath

版本差异:

  • ≤2.3.0.RELEASE:默认为false,调用getPathWithinServletMapping
  • ≥2.3.1.RELEASE:默认为true,调用getPathWithinApplication

区别:

  • getPathWithinServletMapping:对URI进行标准化处理
  • getPathWithinApplication:不进行规范化处理

0x04 解析器

4.1 AntPathMatcher & PathPattern

版本差异:

  • 2.6之前:默认使用AntPathMatcher
  • 2.6及之后:默认使用PathPattern

4.1.1 AntPathMatcher

匹配规则:

  • ?:匹配任意单字符
  • *:匹配0或任意数量字符
  • **:匹配0或任意层级目录
  • {spring:正则表达式}:匹配内容赋值给变量

解析过程:

  1. tokenizePattern()将pattern分割成String数组
  2. tokenizePath()将path分割成string数组
  3. trimTokens属性(4.3.0+默认为false):消除path中的空格

4.1.2 PathPattern

新增{*spring}语法:

  • 匹配剩余path路径并赋值给变量
  • 类似/**,但可获取动态匹配内容

解析过程:

  1. 根据/将URL拆分成多个PathElement对象
  2. 逐个调用PathElementmatches方法匹配
  3. matchOptionalTrailingSeparator(默认为true):
    • Pattern尾部无斜杠时,请求路径有尾部斜杠也能匹配

4.1.3 两者区别

  1. PathPattern

    • 通配符只能定义在尾部
    • 只支持/.两种分隔符
    • 新增{*spring}语法
  2. AntPathMatcher

    • 通配符可在中间
    • 可自定义分隔符
    • 不支持{*spring}语法
Spring Web请求解析过程详解 0x00 前言 Spring MVC框架中, DispatcherServlet 是前端控制器设计模式的实现,作为Spring Web MVC的集中访问点,负责职责的分派。主要职责包括: 文件上传解析(通过 MultipartResolve 处理multipart请求) 通过 HandlerMapping 将请求映射到处理器(返回 HandlerExecutionChain ,包含处理器和多个拦截器) 通过 HandlerAdapter 支持多种类型的处理器 通过 ViewReslver 解析逻辑视图名到具体视图实现 本地化解析 渲染具体视图 异常处理(通过 HandlerExecutionResolver ) 0x01 Spring Web解析过程 以spring-webmvc 5.3.9为例,请求处理流程: Servlet容器调用 DispatcherServlet 的 service 方法(实现在父类 FrameworkServlet 中) 获取请求类型,除PATCH方法外都通过 HttpServlet 的 service 方法处理 根据请求方法调用 processRequest 方法(如GET请求调用 doGet ) 执行 doService 方法后调用 doDispatch 处理请求 doDispatch 方法处理流程: 对multipart请求进行处理 获取对应的 mappedHandler (通过 getHandler 方法) getHandler 方法按顺序循环调用 HandlerMapping 的 getHandler 方法 常见的 HandlerMapping 实现: RequestMappingHandlerMapping :处理注解配置的路由 getHandlerInternal 方法: 从request对象获取请求path 根据path找到 handlerMethod 通过 UrlPathHelper 类进行路径处理 lookupHandlerMethod 方法: 直接根据路径获取对应的Mapping 获取不到时调用 addMatchingMappings 遍历所有 RequestMappingInfo 对象进行匹配 getMatchingCondition 方法(版本差异): 高版本使用 PathPattern 进行URL匹配 2.6之前使用 AntPathMatcher 进行字符串模式匹配 0x02 工具类 2.1 路径处理帮助类UrlPathHelper UrlPathHelper 是Spring的帮助类,用于解析请求中的路径,主要方法: resolveAndCacheLookupPath 方法 getPathWithinApplication 方法: 获取 ContextPath 并进行解码操作 获取 requestUri (通过 request.getRequestURI() ) 对URI进行解码、移除分号内容并清理斜线等处理 decodeAndCleanUriString 方法处理: removeSemicolonContent :根据设置删除分号或Jsessionid decodeRequestString :解码操作 getSanitizedPath :将 // 替换为 / getRemainingPath 方法:将mapping字符与requestUri字符串匹配,忽略分号部分 alwaysUseFullPath 属性: 决定是否经过 getPathWithinServletMapping 方法处理 Spring Boot ≤2.3.0.RELEASE默认为false Spring Boot ≥2.3.1.RELEASE默认为true getPathWithinServletMapping 方法: 调用 getPathWithinApplication 处理 获取 ServletPath (通过 request.getServletPath ) 对URI标准化处理(解码、处理跨目录等) 0x03 关键属性 3.1 SuffixPatternMatch/TrailingSlashMatch SuffixPatternMatch (后缀匹配模式): 以 .xxx 结尾的方式进行匹配 如 /hello 和 /hello.do 匹配结果相同 5.3后 useSuffixPatternMatch 默认值由true变为false TrailingSlashMatch (尾部斜杠匹配): 为true时应用尾部 / 匹配 如 /hello 和 /hello/ 匹配结果相同 3.2 alwaysUseFullPath 版本差异: ≤2.3.0.RELEASE:默认为false,调用 getPathWithinServletMapping ≥2.3.1.RELEASE:默认为true,调用 getPathWithinApplication 区别: getPathWithinServletMapping :对URI进行标准化处理 getPathWithinApplication :不进行规范化处理 0x04 解析器 4.1 AntPathMatcher & PathPattern 版本差异: 2.6之前:默认使用 AntPathMatcher 2.6及之后:默认使用 PathPattern 4.1.1 AntPathMatcher 匹配规则: ? :匹配任意单字符 * :匹配0或任意数量字符 ** :匹配0或任意层级目录 {spring:正则表达式} :匹配内容赋值给变量 解析过程: tokenizePattern() 将pattern分割成String数组 tokenizePath() 将path分割成string数组 trimTokens 属性(4.3.0+默认为false):消除path中的空格 4.1.2 PathPattern 新增 {*spring} 语法: 匹配剩余path路径并赋值给变量 类似 /** ,但可获取动态匹配内容 解析过程: 根据 / 将URL拆分成多个 PathElement 对象 逐个调用 PathElement 的 matches 方法匹配 matchOptionalTrailingSeparator (默认为true): Pattern尾部无斜杠时,请求路径有尾部斜杠也能匹配 4.1.3 两者区别 PathPattern : 通配符只能定义在尾部 只支持 / 和 . 两种分隔符 新增 {*spring} 语法 AntPathMatcher : 通配符可在中间 可自定义分隔符 不支持 {*spring} 语法