Spring源码梳理--SpringMVC是怎样解析请求参数的
发布日期:2021-05-07 20:41:19 浏览次数:30 分类:精选文章

本文共 2517 字,大约阅读时间需要 8 分钟。

SpringMVC是怎样处理一个请求的在前面有写,这里就不在重复,以后再去描叙的更有条理一些。这里说下SpringMVC是怎样解析url上的请求参数的。

 请求的URL: 

Controller : 

@RestControllerpublic class MyController {    @RequestMapping(value = "hello",method = RequestMethod.GET)    public String hello(@RequestParam String name, @RequestParam Integer age)    {        return "Hello " + name + " - " + age;    }}

 

然后我们直接从 DispatcherServlet 的 doDispatch 方法开始:

  

然后到Adapter的handle方法:

这里我们需要知道HandlerMethod类(

理解为对

RequestMapping(value = "hello",method = RequestMethod.GET)

public String hello(@RequestParam String name, @RequestParam Integer age) 方法的封装

  ):

public class HandlerMethod {    protected final Log logger = LogFactory.getLog(this.getClass());    private final Object bean;    @Nullable    private final BeanFactory beanFactory;    private final Class
beanType; private final Method method; private final Method bridgedMethod; private final MethodParameter[] parameters; @Nullable private HttpStatus responseStatus; @Nullable private String responseStatusReason; @Nullable private HandlerMethod resolvedFromHandlerMethod; @Nullable private volatile List
interfaceParameterAnnotations; private final String description;

    这些属性差不多可以见名知意,再看下具体的值就知道了,不过多叙述了:

然后可以看到parameters属性有两个,MethodParameter就是描叙Controller方法的请求参数的:

   在adapter的invokeHandlerMethod方法 会通过HandlerMethod对象产生一个:ServletInvocableHandlerMethod对象:

然后执行此对象:

  

然后到这里就是真正去执行Handler了:

两步:   第一步就是获取执行方法的请求参数,第二步就是执行方法。 这篇文章主要是梳理下是怎样获取请求参数的。

 

有两个参数:

但我们可以看到其属性的值:parameterName是空的。下面就是将其名称填进去,看其表示的是name,还是age。

  

我们看下这个resolvers

这两个方法表示的是,支不支持解析这个MethodParameter。

支持的话就用resolveArgument方法去解析:

   我们再看下HandlerNethodResolver是怎样去判断的(Annotation表示的是注解):

   hasParameterAnnotation()方法就是判断有没有这个注解,(下面的参数RequestHeader、RequestParam都是注解)

1、类RequestHeaderMethodArgumentResolver

2、类RequestParamMethodArgumentResolver

通过RequestParam可以知道我们这里应该用的Resolver就是RequestParamMethodArgumentResolver

 

我们再看下是怎样解析方法所需的参数名称的:

这里就是将RequestParam注解中的内容填充进来:

   

 

这里有两个方法:createNamedValueInfo、updateNamedValueInfo。

createNamedValueInfo就是将你在RequestParam注解中的内容写到NameValueInfo中。

updateNamedValueInfo:

     

   如果你在注解中没有写name,就会调:parameter.getParameterName();去获取,这里就会有些复杂了,第一次获取时其要通过解析class文件去获取(因为方法的测试名编译时应该是用arg0、arg1表示的,并不是我们写的String name,Integer age,根据以往看到有些内容确认的,并没有通过具体的验证,这个地方现在不能确认为什么还要通过读取解析class文件去获取方法的具体参数名),所以我们在用RequestParam注解时还是将name写上比较好。

解析之后我们再来看下MethodParameter类:

type与name已经有啦。

 

获取到名称后,接下来就是从request中去获取对应的值了:

直接从request中获取(前面还会有其它一些情况获取返回,这里说下普通情况,看下其流程):

这里这里获取的value就是String类型,但是我们的入参会有其它的类型,如Integer、Long等,所以还需要进行类型转换。

关于转换的知识点之后再写。

上一篇:计算机网络知识点梳理
下一篇:梳理 tomcat 是怎样解析一个请求的

发表评论

最新留言

初次前来,多多关照!
[***.217.46.12]2025年03月29日 15时21分45秒