从@PathVariable中学习获取path variable方法

背景

为使用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继承了接口WebRequestWebRequest继承了接口RequestAttributes。通过打断点,确认了这里的request对象是ServletWebRequest对象,这个类继承自ServletRequestAttributes这里的运行逻辑可以继续深入探究)。
RequestContextHolder提供了static方法currentRequestAttributes()可以获取当前线程的RequestAttributes对象(可转换成ServletRequestAttributes对象),ServletRequestAttributes对象中封装了HttpServletRequest,而HttpServletRequest提供了类似ServletWebRequestgetAttribute()方法可以获取path variables。
这就意味着可以通过如下代码获得的path variablesmap,通过这个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);

你可能感兴趣的:(spring,java,spring,PathVariable)