为使用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, String> uriTemplateVars = (Map<String, String>) request.getAttribute(
HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, RequestAttributes.SCOPE_REQUEST);
return (uriTemplateVars != null ? uriTemplateVars.get(name) : null);
}
上述代码中的接口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, String> pathVariables = (Map<String, String>) request.getAttribute(
HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
HttpServletRequest request = ((ServletRequestAttributes)requestAttributes).getRequest();
Map<String, String> pathVariables = (Map<String, String>) request.getAttribute(
HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
String pathVariable = (pathVariables != null ? pathVariables.get("pathVariable") : null);