背景 为使用spring aop
解耦一个web请求中的通用逻辑,需要用到请求的uri中的参数。在web请求的controller
中可以使用@PathVariable
来获取对应参数,如何手动从HttpServletRequest
中获取就是要研究的问题。
分析
- 库版本
spring-webmvc 5.2.1.RELEASE
spring-web 5.2.1.RELEASE
tomcat-embed-core 9.0.27
- 涉及类与接口
org.springframework.web.servlet.mvc.method.annotation.PathVariableMethodArgumentResolver
org.springframework.web.context.request.NativeWebRequest
org.springframework.web.context.request.WebRequest
org.springframework.web.context.request.RequestAttributes
org.springframework.web.context.request.RequestContextHolder
org.springframework.web.context.request.ServletWebRequest
org.springframework.web.context.request.ServletRequestAttributes
javax.servlet.http.HttpServletRequest
@PathVariable
注解的代码
@Override
@SuppressWarnings("unchecked")
@Nullable
protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest request) throws Exception {
Map, String> uriTemplateVars = (Map, String>) request.getAttribute(
HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, RequestAttributes.SCOPE_REQUEST);
return (uriTemplateVars != null ? uriTemplateVars.get(name) : null);
}
【spring|从@PathVariable中学习获取path variable方法】上述代码中的接口
NativeWebRequest
继承了接口WebRequest
, WebRequest
继承了接口RequestAttributes
。通过打断点,确认了这里的request
对象是ServletWebRequest
对象,这个类继承自ServletRequestAttributes
(这里的运行逻辑可以继续深入探究)。RequestContextHolder
提供了static
方法currentRequestAttributes()
可以获取当前线程的RequestAttributes
对象(可转换成ServletRequestAttributes
对象),ServletRequestAttributes
对象中封装了HttpServletRequest
,而HttpServletRequest
提供了类似ServletWebRequest
的getAttribute()
方法可以获取path variables。这就意味着可以通过如下代码获得的
path variables
map,通过这个map可获得对应变量值。RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
HttpServletRequest request = ((ServletRequestAttributes)requestAttributes).getRequest();
Map, String> pathVariables = (Map, String>) request.getAttribute(
HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
编码方案
RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
HttpServletRequest request = ((ServletRequestAttributes)requestAttributes).getRequest();
Map, String> pathVariables = (Map, String>) request.getAttribute(
HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
String pathVariable = (pathVariables != null ? pathVariables.get("pathVariable") : null);
推荐阅读
- Java|Java基础——数组
- 人工智能|干货!人体姿态估计与运动预测
- java简介|Java是什么(Java能用来干什么?)
- Java|规范的打印日志
- Linux|109 个实用 shell 脚本
- 程序员|【高级Java架构师系统学习】毕业一年萌新的Java大厂面经,最新整理
- Spring注解驱动第十讲--@Autowired使用
- =======j2ee|spring用注解实现注入的@resource,@autowired,@inject区别
- SqlServer|sql server的UPDLOCK、HOLDLOCK试验
- jvm|【JVM】JVM08(java内存模型解析[JMM])