springMVC中@RequestParam和@RequestBody的区别

    技术2022-07-10  141

    本文使用postman来测试springMVC的@RequestParam和@RequestBody注解的区别。 测试数据为:

    @RequestBody

    @RequestMapping("test") @ResponseBody public User test(@RequestBody User user) { return user; }

    @RequestBody的作用:

    @RequestBody可以接收POST请求content-type为application/json的参数,消息体中的参数为json格式,springmvc会使用MappingJackson2HttpMessageConverter将json格式的参数转换为java对象,MappingJackson2HttpMessageConverter默认支持的格式为content-type:application/json。

    说明:测试@RequestBody时,发送的都是POST请求

    1.测试content-type:application/json

    测试结果为:

    2.测试content-type:application/x-www-form-urlencoded

    测试结果为: 后台出现了错误,查看控制台,错误信息为:

    2020-07-01 18:02:24.358 WARN 4060 --- [io-8081-exec-10] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported]

    原因是MappingJackson2HttpMessageConverter默认只支持content-type:application/json。 手动配置MappingJackson2HttpMessageConverter的supportedMediaTypes属性,增加对application/x-www-form-urlencoded;charset=UTF-8的支持,然后继续测试。

    @Bean public HttpMessageConverters jsonHttpMessageConverters() { MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); List<MediaType> supportedMediaTypes = new ArrayList<>(); supportedMediaTypes.add(MediaType.APPLICATION_JSON); supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED); converter.setSupportedMediaTypes(supportedMediaTypes); return new HttpMessageConverters(converter); }

    后台错误信息为: 是因为json格式不正确,content-type:application/x-www-form-urlencoded发送的http请求参数是键值对的格式,如下图:

    @RequestParam

    @RequestParam的作用:

    @RequestParam可以接收POST请求content-type:application/x-www-form-urlencoded和GET请求url的querystring里的参数。不能使用封装的对象接收参数,只能将参数单独接收,但可以将参数用一个map接收 @RequestMapping("test") @ResponseBody public User test(@RequestParam(required = false) User user) { return user; }

    1.测试content-type:application/json

    user为null

    2.测试content-type:application/x-www-form-urlencoded

    user为null 以上可以看出,@RequestParam注解无法将参数与User对象进行绑定,我们将后台代码改为如下后再测试:

    @RequestMapping("test") @ResponseBody public User test(@RequestParam(required = false) String userName,@RequestParam(required = false) String password) { User user = new User(); user.setUserName(userName); user.setPassword(password); return user; }

    测试content-type:application/json**

    由于content-type:application/json为json格式,不是键值对的格式的参数,使用@RequestParam是无法接收的

    测试content-type:application/x-www-form-urlencoded**

    1.使用post请求:

    2.使用get请求:

    使用get请求时,@RequestParam并没有接收到参数,这是因为postman将参数放在了消息体中,当是get类型的请求时,@RequestParam会解析url的querystring里的参数,所以在这里后台的userName和password为null。 从这里也可以看出来,其实http的get请求,参数也可以放在消息体中,只不过浏览器对于get请求,是将参数拼到url后面。除了浏览器,在其他地方(比如httpClient)使用http将参数放到消息体中也是没问题的。如果在浏览器使用ajax或form表单测试get请求时,后台就能够接收到。在controller的带@RequestMapping的方法中如果是简单类型的参数(如String,Integer等,由spring的BeanUtils#isSimpleProperty判断),参数会默认使用@RequestParam。

    Processed: 0.013, SQL: 9