org.apache.catalina.connector.Request 中 getParameterMap

1

org.apache.catalina.connector.Request 中 getParameterMap的实现如下: @Override
public Map<String, String[]> getParameterMap() {
if (parameterMap.isLocked()) {
return parameterMap;
}
Enumeration enumeration = getParameterNames();
while (enumeration.hasMoreElements()) {
String name = enumeration.nextElement();
String[] values = getParameterValues(name);
parameterMap.put(name, values);
}
parameterMap.setLocked(true);
return parameterMap;
} 他为什么要setLocked设置锁呢?

org.apache.catalina.connector.Request 类中的 getParameterMap() 实现提供了一个请求参数的映射,这个映射是通过 Tomcat Servlet 容器内部的逻辑构建的。调用 setLocked(true) 是为了锁定参数映射(parameterMap),这样一旦参数被首次访问并解析,它们就不再改变。

在Servlet API中,请求参数的映射必须是只读的。一旦参数被读取,整个参数映射就应该被锁定,以避免在请求处理的过程中发生对参数的改动,保持请求的不变性。这有几个原因:

线程安全:HTTP请求可能被多个线程并发处理。如果参数映射不是只读的,那么并发的线程可能会试图修改它,从而导致并发问题。

一致性:一旦请求处理开始,期望请求的参数保持不变,以确保在请求处理过程中,所有组件(过滤器、Servlet等)看到的是一致的参数集。

规范要求:Servlet规范要求请求参数只能读取一次,之后就应该是不可变的。这是为了确保应用程序的可预测性和数据的一致性。

setLocked(true)方法实际上是Tomcat特有的,不是Servlet API的一部分,但它实现了相同的目的。一旦parameterMap被锁定后,它就不能被修改,任何试图修改它的操作都会引发异常。这种设计模式保证了请求的参数映射一旦被创建,就保持不变,符合Servlet规范的要求,并确保了应用程序的稳定性和安全性。

2

Spring的@RequestParam, @PathVariable, @RequestBody等注解已经提供了更为简洁和声明式的方式来绑定请求参数到控制器方法的参数。他们的底层实现是怎么获取具体的参数的,调用的是getQueryString还是getParameterMap

Spring框架中的@RequestParam、@PathVariable、@RequestBody等注解的参数绑定并不直接调用HttpServletRequest的getQueryString()或getParameterMap()方法。Spring框架使用一组称为HandlerMethodArgumentResolver的组件来处理控制器方法参数的解析和绑定。

每个HandlerMethodArgumentResolver负责处理特定类型的方法参数。当一个HTTP请求被映射到控制器方法时,Spring会遍历所有已注册的HandlerMethodArgumentResolver,并找到支持当前方法参数的解析器来处理该参数。以下是一些主要注解的解析器和其工作方式的简要说明:

@RequestParam:

解析器:RequestParamMethodArgumentResolver
工作方式:这个解析器会处理标注有@RequestParam的方法参数。它通过ServletRequest的getParameter(String name)方法来获取单个请求参数的值。如果需要获取所有请求参数,它可以使用getParameterMap()方法来获取参数的Map。这样一来,getQueryString()就不会被直接使用,因为Spring处理的是解析后的参数。
@PathVariable:

解析器:PathVariableMethodArgumentResolver
工作方式:这个解析器处理标注有@PathVariable的方法参数。它使用URI模板变量的值来绑定到方法参数上。这些变量值是通过Spring MVC的前端控制器DispatcherServlet解析URL路径得到的,并存储在一个 Map 中,而非使用getQueryString()。
@RequestBody:

解析器:RequestResponseBodyMethodProcessor
工作方式:这个解析器负责处理标注有@RequestBody的方法参数。它使用消息转换器(HttpMessageConverter)来解析请求体内容。对于JSON或XML数据,将使用相应的HttpMessageConverter实现来将请求体中的数据反序列化为Java对象。
@RequestHeader:

解析器:RequestHeaderMethodArgumentResolver
工作方式:这个解析器使用ServletRequest的getHeader(String name)方法来获取HTTP请求头的值。
@CookieValue:

解析器:CookieValueMethodArgumentResolver
工作方式:这个解析器使用HttpServletRequest的getCookies()方法来从请求中获取cookie值。
Spring的方法参数解析是一个非常灵活和强大的机制,允许开发者通过自定义HandlerMethodArgumentResolver来扩展和自定义方法参数的处理。这些解析器使得Spring能够提供声明式的请求参数绑定,同时隐藏了底层的实现细节,使得控制器方法的代码变得更加简洁和易于维护。

  • 16
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值