← Back to list

Controller 方法参数

Published on: | Views: 103

Controller中方法可以有非常多的参数, 具体见: https://docs.spring.io/spring/docs/5.1.9.RELEASE/spring-framework-reference/web.html#mvc-ann-methods

下面简单介绍一下比较常用的几个参数注解。

无注解

If a method argument is not matched to any of the earlier values in this table and it is a simple type (as determined by BeanUtils#isSimpleProperty, it is a resolved as a @RequestParam. Otherwise, it is resolved as a @ModelAttribute.

如果一个方法的参数没有注解,那么这样处理: - 如果参数是简单类型 :a primitive, a String or other CharSequence, a Number, a Date, a URI, a URL, a Locale, a Class, or a corresponding array. 这时候被当作@RequestParam处理(不是必须有值); - 如果参数是复杂类型,那么会被当作@ModelAttribute处理;

简单来说,对于请求参数(跟在url上面的和form中的),可以使用简单类型或者复杂类型来接收,比如如下请求:

GET http://192.168.1.26:20540/test1?a=1&b=xx

接收方法1: test(Integer a, String b) 会被转换成 test(@RequestParams(required=false) Integer a, @RequestParams(required=false) String b) 处理

接收方法2: test(TestDto dto) 会被转换成 test(@ModelAttribute dto) 处理

@RequestParams

从request的请求参数(跟在url上面的和form中的)中取出相同名称的参数,对于如下 请求

GET "http://192.168.1.26:20540/test1?a=1&b=xx"
POST "http://192.168.1.26:20540/test4" -d 'a=1&b=xx' 

使用 test(@RequestParams Integer a, @RequestParams String b) 都能获取到a和b的值。

@RequestBody

从body中取出数据,并且使用HttpMessageConverter反序列化为一个对象,参数名称不重要,对于json方式的,请求时要指定类型 content-type: application/json 对于GET方式的请求,也可以从body中取对象,但是一般不建议,因为很多第三方库默认为GET没有设置body的方法(实际上http协议并没有说get不能有body)

@ModelAttribute

它会创建一个model对象(如果没有的话), 然后使用请求中的参数,覆盖对象里的同名成员。

总结

对于GET方法, 前端一般是将参数加到url后面, 如 http://xxxx?a=xxxx&b=yyyy&c=zzzz 等方式, 那么后端的Controll中接收的时候,参数较少的时候,可以使用@RequestParams接收, 参数多的时候,可以使用不带注解的对象来接收,也可以使用@ModelAttribute来接收。 对于POST方法,前端默认是使用form格式(application/x-www-form-urlencoded)将数据放到body中传输, 那么参数少的时候,可以使用@RequestParams接收, 参数多的时候,可以使用不带注解的对象来接收,也可以使用@ModelAttribute来接收。而对于要求统一使用json传输的项目, 就需要使用@RequestBody来接收。

在使用无参数的复杂对象或者@ModelAttribute接收时,如果对象没有getter/setter接口,那么数据不能正确接收,即使数据是public的。