注解@RequestParam与@RequestBody的使用场景

本文详细解析了SpringMVC框架中@RequestBody和@RequestParam注解的使用场景及区别,包括如何处理不同Content-Type的数据,如application/json和application/x-www-form-urlencoded,以及批量数据的处理方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

两种方法

方法1

如果使用spring mvc同客户端通信,完全使用json数据格式,需要增加RequestBody注解,函数参数为自定义类

@Controller
public class TestController{
  @RequestMapping("\test")
  @ResponseBody
  public RetureResult test(@RequestBody User user){
    return new ReturnResult();
  }  
}

这样,可以将接收到的json格式的数据转换为指定的数据对象user。比如{name:"test"},name为User类的属性域。通过ResponseBody注解,可以返回json格式的数据。

但是有时接收json格式数据时,我们可能需要将其转换为多个对象,以上方式是不支持在方法变量中直接定义多个传参的。

以下方式是错误的。原因是request的content-body是以流的形式进行读取的,读取完一次后,便无法再次读取了。

@Controller
public class TestController{
  @RequestMapping("\test")
  @ResponseBody
  public RetureResult test(@RequestBody User user,@RequestBody Address address){
    return new ReturnResult();
  }  
}

此时可使用一种变通的方法达到此目的。

在TestController.java文件中增加一个包装类

@Controller
public class TestController{
  @RequestMapping("\test")
  @ResponseBody
  public RetureResult test(@RequestBody Param param){
    return new ReturnResult();
  }  
}
class Param{
  public User user;
  public Address address;  
}

注意:类中属性必须为public,或者有setter和getter;Param类中的属性只能比json中的属性多,不能少。

此时传输的json数据格式变为{user:{name:"test"},address:{location:"新华路"}}。

由于只是在TestController中增加一个包装类,不会影响其他的类以及已经定义好的model类,因此可以非常方便的达到接收多个对象参数的目的。

 方法2

将接收参数定义为Map<String, Object>,然后使用map转object工具,转换成需要的对象。

此时,即使自定义的Param类中的属性即使比json数据中的属性少了,也没关系。

其中JSONUtils为自定义的工具类,可使用常见的fastjson等工具包包装实现。

@Controller
public class TestController{
  @RequestMapping("\test")
  @ResponseBody
  public Object test(@RequestBody Map<String, Object> models){
   User user=JsonXMLUtils.map2object((Map<String, Object>)models.get("user"),User.class); 
   Address address=JsonXMLUtils.map2object((Map<String, Object>)models.get("address"),Address.class); 
   return models; 
 }
}
import com.alibaba.fastjson.JSON;

public class JsonXMLUtils {
    public static String obj2json(Object obj) throws Exception {
        return JSON.toJSONString(obj);
    }

    public static <T> T json2obj(String jsonStr, Class<T> clazz) throws Exception {
        return JSON.parseObject(jsonStr, clazz);
    }

    public static <T> Map<String, Object> json2map(String jsonStr)     throws Exception {
            return JSON.parseObject(jsonStr, Map.class);
    }
  
    public static <T> T map2obj(Map<?, ?> map, Class<T> clazz) throws Exception {
        return JSON.parseObject(JSON.toJSONString(map), clazz);
    }
}

二、@RequestParam

先介绍一下@RequestParam的使用场景:

注解@RequestParam接收的参数是来自requestHeader中,即请求头通常用于GET请求,比如常见的url:http://localhost:8081/spring-boot-study/novel/findByAuthorAndType?author=唐家三少&type=已完结,其在Controller 层的写法如下图所示:

@RequestParam有三个配置参数:

  • required 表示是否必须,默认为 true,必须。
  • defaultValue 可设置请求参数的默认值。
  • value 为接收url的参数名(相当于key值)。

@RequestParam用来处理 Content-Type 为 application/x-www-form-urlencoded 编码的内容,Content-Type 默认为该属性。

@RequestParam也可用于其它类型的请求,例如:POST、DELETE等请求。比如向表中插入单条数据,Controller 层的写法如下图所示:

@RequestParam有三个配置参数:

  • required 表示是否必须,默认为 true,必须。
  • defaultValue 可设置请求参数的默认值。
  • value 为接收url的参数名(相当于key值)。

@RequestParam用来处理 Content-Type 为 application/x-www-form-urlencoded 编码的内容,Content-Type 默认为该属性。

@RequestParam也可用于其它类型的请求,例如:POST、DELETE等请求。比如向表中插入单条数据,Controller 层的写法如下图所示:

由于@RequestParam是用来处理 Content-Type 为 application/x-www-form-urlencoded 编码的内容的,所以在postman中,要选择body的类型为 x-www-form-urlencoded,这样在headers中就自动变为了 Content-Type : application/x-www-form-urlencoded 编码格式。如下图所示:

但是这样不支持批量插入数据啊,如果改用 json 字符串来传值的话,类型设置为 application/json,点击发送的话,会报错,后台接收不到值,为 null

这时候,注解@RequestBody就派上用场了。继续往下看 ↓

 

三、@RequestBody

先介绍一下@RequestBody的使用场景:

如果为post请求时,则后台接收参数的注解就是为RequestBody(看请求报文是否设置成JSON格式)

注解@RequestBody接收的参数是来自requestBody中,即请求体。一般用于处理非 Content-Type: application/x-www-form-urlencoded编码格式的数据,比如:application/jsonapplication/xml等类型的数据。

application/json类型的数据而言,使用注解@RequestBody可以将body里面所有的json数据传到后端,后端再进行解析。

三、@RequestBody

先介绍一下@RequestBody的使用场景:

注解@RequestBody接收的参数是来自requestBody中,即请求体。一般用于处理非 Content-Type: application/x-www-form-urlencoded编码格式的数据,比如:application/jsonapplication/xml等类型的数据。

application/json类型的数据而言,使用注解@RequestBody可以将body里面所有的json数据传到后端,后端再进行解析。

3.1 向表中批量插入数据

举个批量插入数据的例子,Controller层的写法如下图所示:

由于@RequestBody可用来处理 Content-Type 为 application/json 编码的内容,所以在postman中,选择body的类型为row -> JSON(application/json),这样在 Headers 中也会自动变为 Content-Type : application/json 编码格式。body内的数据如下图所示:

批量向表中插入两条数据,这里的 saveBatchNovel()方法已经封装了 JPA的 saveAll() 方法。body 里面的 json 语句的 key 值要与后端实体类的属性一一对应。

注意:前端使用$.ajax的话,一定要指定 contentType: "application/json;charset=utf-8;",默认为 application/x-www-form-urlencoded

3.2 后端解析json数据

上述示例是传递到实体类中的具体写法,那么如果传递到非实体类中,body里面的json数据需要怎么解析呢?我们再来看下面这个例子:

在body中,我们还是输入上面的json数据,根据分析,上面的json数据是一个List数组内嵌套着map对象,那么在后台的接收形式可写为 List<Map<String, String>>,具体代码如下图所示:

postman请求:

控制台输出:

得出结论,通过@RequestBody可以解析Body中json格式的数据。

四、总结

注解@RequestParam接收的参数是来自requestHeader中,即请求头通常用于GET请求,像POST、DELETE等其它类型的请求也可以使用。

注解@RequestBody接收的参数是来自requestBody中,即请求体。一般用于处理非 Content-Type: application/x-www-form-urlencoded编码格式的数据,比如:application/jsonapplication/xml等类型的数据。通常用于接收POST、DELETE等类型的请求数据,GET类型也可以适用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

、小H

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值