@controller报错_详解SpringMVC中Controller的方法中参数的工作原理[附带源码分析]

本文深入探讨了SpringMVC中Controller方法参数的工作原理,包括@RequestBody、@RequestParam注解的区别,以及如何处理自定义参数。通过源码分析,揭示了SpringMVC如何利用HandlerMethodArgumentResolver和HandlerMethodReturnValueHandler接口处理请求和响应。文中还介绍了如何解决常见的参数处理问题,如日期格式错误和自定义参数解析,并提供了编写自定义HandlerMethodArgumentResolver的示例。
摘要由CSDN通过智能技术生成

前言

SpringMVC是目前主流的Web MVC框架之一。

如果有同学对它不熟悉,那么请参考它的入门blog:http://www.cnblogs.com/fangjian0423/p/springMVC-introduction.html

SpringMVC中Controller的方法参数可以是Integer,Double,自定义对象,ServletRequest,ServletResponse,ModelAndView等等,非常灵活。本文将分析SpringMVC是如何对这些参数进行处理的,使读者能够处理自定义的一些参数。

现象

本文使用的demo基于maven。我们先来看一看对应的现象。

@Controller
@RequestMapping(value = "/test")
public class TestController {
    
  
  @RequestMapping("/testRb")
  @ResponseBody
  public Employee testRb(@RequestBody Employee e) {
    
    return e;
  }
  
  @RequestMapping("/testCustomObj")
  @ResponseBody
  public Employee testCustomObj(Employee e) {
    
    return e;
  }
  
  @RequestMapping("/testCustomObjWithRp")
  @ResponseBody
  public Employee testCustomObjWithRp(@RequestParam Employee e) {
    
    return e;
  }
  
  @RequestMapping("/testDate")
  @ResponseBody
  public Date testDate(Date date) {
    
    return date;
  }
  
}

首先这是一个Controller,有4个方法。他们对应的参数分别是带有@RequestBody的自定义对象、自定义对象、带有@RequestParam的自定义对象、日期对象。

接下来我们一个一个方法进行访问看对应的现象是如何的。

首先第一个testRb:

ec4b55cac41a8585ef7fac34e8f881f0.png

第二个testCustomObj:

32e057b80d2588c50cfdd6726cd57ef1.png

第三个testCustomObjWithRp:

eb1032797cbdbfdf2ffe255759151b3a.png

第四个testDate:

e55e39cfeeff9eca8cac9c8c9c3b6510.png

为何返回的Employee对象会被自动解析为xml,请看楼主的另一篇博客:戳我

为何Employee参数会被解析,带有@RequestParam的Employee参数不会被解析,甚至报错?

为何日期类型不能被解析?

SpringMVC到底是如何处理这些方法的参数的?

@RequestBody、@RequestParam这两个注解有什么区别?

带着这几个问题。我们开始进行分析。

源码分析

本文所分析的源码是Spring版本4.0.2

在分析源码之前,首先让我们来看下SpringMVC中两个重要的接口。

两个接口分别对应请求方法参数的处理、响应返回值的处理,分别是HandlerMethodArgumentResolverHandlerMethodReturnValueHandler,这两个接口都是Spring3.1版本之后加入的。

0c87c693f9e5b42cddfc1dc17e251181.png

a7e46826532f47e1fbbac42a9455649a.png

SpringMVC处理请求大致是这样的:

首先被DispatcherServlet截获,DispatcherServlet通过handlerMapping获得HandlerExecutionChain,然后获得HandlerAdapter。

HandlerAdapter在内部对于每个请求,都会实例化一个ServletInvocableHandlerMethod进行处理,ServletInvocableHandlerMethod在进行处理的时候,会分两部分别对请求跟响应进行处理

之后HandlerAdapter得到ModelAndView,然后做相应的处理。

本文将重点介绍ServletInvocableHandlerMethod对请求以及响应的处理。

6934025a42b9aabeee377ffd021e7e9d.png

1. 处理请求的时候,会根据ServletInvocableHandlerMethod的属性argumentResolvers(这个属性是它的父类InvocableHandlerMethod中定义的)进行处理,其中argumentResolvers属性是一个HandlerMethodArgumentResolverComposite类(这里使用了组合模式的一种变形),这个类是实现了HandlerMethodArgumentResolver接口的类,里

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值