使用注解@RequestParam@RequestBody获得表单数据

使用@RequestParam

Use the @RequestParam annotation to bind request parameters to a method parameter in your controller.

首先定义User

public class User {
    private String phone;
    private String password;
    private String slat;
    private boolean locked;
...
Getter and Setter
...
  1. 在前端通过表单提交数据,如果http请求是GET,则表单参数会以放入URL的查询参数中,例如:
    http://localhost:port/...?phone=value1&password=value2
    
    那么 ,在后端Controller中,可以通过Request.getParamater()方法获取表单数据,也可以通过@RequestParam注解将数据绑定在参数上。
    @RequestMapping("form")
    @ResponseBody
    public User form(@RequestParam("phone")String phone,@RequestParam("password")String password){
        return new User(phone,password);
    }
    

在这里插入图片描述

  1. 如果请求方法是POST,表单数据存在请求体中。由于Tomcat对于Content-Typeapplication/x-www-form-urlencoded(POST请求)做了“特殊处理”,使得可以通request.getParamter()将值取出,所以可以在Controller方法参数上加上@RequestParam将数据绑定在参数上。
    在这里插入图片描述

    Tomcat的HttpServletRequest类的实现类为org.apache.catalina.connector.Request(实际上是org.apache.coyote.Request),而它对处理请求参数的方法为protected void parseParameters(),这个方法中对Content-Type multipart/form-data(文件上传)和application/x-www-form-urlencoded(POST请求)的处理代码如下:

    protectedvoid parseParameters() {
               //省略部分代码......
               parameters.handleQueryParameters();// 这里是处理url中的参数
               //省略部分代码......
               if ("multipart/form-data".equals(contentType)) { // 这里是处理文件上传请求
                    parseParts();
                    success = true;
                    return;
               }
     
               if(!("application/x-www-form-urlencoded".equals(contentType))) {// 这里如果是非POST请求直接返回,不再进行处理
                    success = true;
                    return;
               }
               //下面的代码才是处理POST请求参数
               //省略部分代码......
               try {
                    if (readPostBody(formData, len)!= len) { // 读取请求体数据
                        return;
                    }
               } catch (IOException e) {
                    // Client disconnect
                    if(context.getLogger().isDebugEnabled()) {
                        context.getLogger().debug(
                                sm.getString("coyoteRequest.parseParameters"),e);
                    }
                    return;
               }
               parameters.processParameters(formData, 0, len); // 处理POST请求参数,把它放到requestparameter map中(即request.getParameterMap获取到的Map,request.getParameter(name)也是从这个Map中获取的)
               // 省略部分代码......
    }
     
       protected int readPostBody(byte body[], int len)
           throws IOException {
     
           int offset = 0;
           do {
               int inputLen = getStream().read(body, offset, len - offset);
               if (inputLen <= 0) {
                    return offset;
               }
               offset += inputLen;
           } while ((len - offset) > 0);
           return len;
        }
    

    从上面代码可以看出,在sevlet实现中,mutipart/form-data和application/x-www-form-urlencoded会被特殊处理,请求参数将被放置于request.paramter,这是一个map。我们可以从map中获取参数.。所以可以通过request,getParamater()和@RequestParam将数据取出来。

如果发起HTTP POST请求时,没有指定Content-type=application/x-www-form-urlencoded会如何?

在这里插入图片描述

首先,服务器为什么会对表单提交和文件上传做特殊处理,因为表单提交数据是名值对的方式,且Content-Type为application/x-www-form-urlencoded,而文件上传服务器需要特殊处理,普通的POST请求(Content-Type不是application/x-www-form-urlencoded)数据格式不固定,不一定是名值对的方式,所以服务器无法知道具体的处理方式,所以只能通过获取原始数据流的方式来进行解析。
此时,默认的Cotent-type=text/plain,这时服务器就不知道怎么解析数据了,所以才只能通过获取原始数据流的方式来进行解析请求数据,不能使用@RequestParam绑定数据。

Content-Type不是application/x-www-form-urlencoded的POST请求是不会读取请求体数据和进行相应的参数处理的,即不会解析表单数据来放到request parameter map中。所以通过request.getParameter(name)是获取不到的。

使用@RequestBody

  1. 在Controller方法中使用@RequestBody注解,请求头中的Content-type设置为application/x-www-form-urlencoded,Spring会使用FormHttpMessageConverter将表单数据写入MultiValueMap<String,String>中,在controller方法中可以通过map获得表单数据。

    @RequestMapping("form1")
    @ResponseBody
    public User form1(@RequestBody MultiValueMap<String,String> user){
        String phone = user.getFirst("phone");
        String password = user.getFirst("password");
        return new User(phone,password);
    }
    

    在这里插入图片描述

  2. 请求头中的Content-type设置为application/json,将数据使用JSON数据格式传递后端,默认使用MappingJackson2HttpMessageConvert将其转换相应的参数类型。

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

在这里插入图片描述

————————————————

原文链接:https://blog.csdn.net/mhmyqn/article/details/25561535

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
@RequestParam和@RequestBodySpring框架中常用的注解,用于处理HTTP请求参数的绑定。它们可以同时使用,用于处理不同类型的请求参数。 @RequestParam注解用于将请求参数绑定到方法的参数上。它可以用于绑定URL路径中的参数、查询参数或表单参数。通过@RequestParam注解,我们可以指定参数的名称、是否必需以及默认值等信息。 @RequestBody注解用于将请求体中的数据绑定到方法的参数上。它通常用于处理POST请求中的JSON或XML数据。通过@RequestBody注解,我们可以将请求体中的数据转换为Java对象,并在方法中进行处理。 当@RequestParam和@RequestBody同时使用时,通常是为了处理复杂的请求场景。比如,一个POST请求既包含了请求体中的JSON数据,又包含了URL路径中的参数或查询参数。在这种情况下,我们可以使用@RequestParam注解获取URL路径中的参数或查询参数,使用@RequestBody注解获取请求体中的JSON数据。 例如,下面是一个使用@RequestParam和@RequestBody同时使用的示例: ```java @PostMapping("/user/{id}") public void updateUser(@PathVariable("id") Long id, @RequestParam("name") String name, @RequestBody User user) { // 根据id更新用户信息 // name为URL路径中的参数 // user为请求体中的JSON数据 } ``` 在上述示例中,`@PathVariable("id")`用于获取URL路径中的id参数,`@RequestParam("name")`用于获取URL路径中的name参数,`@RequestBody User user`用于获取请求体中的JSON数据,并将其转换为User对象。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值