Spring源码梳理--SpringMVC是怎样解析请求参数的

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

 请求的URL: http://localhost:8080/hello?name=jhf&age=16

Controller : 

@RestController
public 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<Annotation[][]> 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等,所以还需要进行类型转换。

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值