← 返回首页
SpringMVC教程(十三)
发表时间:2020-06-10 16:26:42
@RequestParam与@RequestBody

在Controller中使用@RequestParam和@RequestBody都可以用来接收请求参数,但是它们的使用场景还是有区别的。

1.@RequestParam

@RequestParam总体上来说,该注解类拥有三个参数: 1)value、name 属性都标识请求参数名(必须配置); 2)required:参数是否必传,默认为 true,可以设置为非必传 false;(如果设置了必传或默认,请求未传递参数,将会抛出异常); 3)defaultValue:参数默认值,如果设置了该值,required 将会自动设置为 false;

@RequestParam注解获取的参数放在请求哪? 1)get请求的 requestHeaders 中 content-type 这个字段,使用 form-data 表单形式携带参数请求; 2)Spring中的@RequestParam注解接收的参数大多数场景是来自requestHeaders中,即请求头,也就是url中,格式为:http://localhost:8080/appdemo/xxx?username=zhangsan&password=1234,由于 url 长度有限制,所以参数需要限制数量和值得长度;

实例: 以用户登录动作为例,使用@RequestParam接收请求参数。

package com.controller;

import com.entity.Users;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("users")
public class UsersController {

    @GetMapping(value="session")
    public Users login(@RequestParam(value = "username",required = true) String username,@RequestParam(value="password",required = true) String password){
        System.out.println("执行用户登录,获取用户session....");
        System.out.println("用户名:"+username+",密码:"+password);
        Users loginUser = new Users(100,username,password);
        return loginUser;
    }

}

使用PostMan测试登录接口。

服务器控制台输出结果如下:

执行用户登录,获取用户session....
用户名:zhangsan,密码:123456

当然也可以不使用@RequestParam注解直接进行对象属性赋值(不推荐使用,容易和@ReuqestBody混淆)。

package com.controller;

import com.entity.Users;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("users")
public class UsersController {

    @GetMapping(value="session")
    public Users login(Users user){
        System.out.println("执行用户登录,获取用户session....");
        System.out.println("用户名:"+user.getUsername()+",密码:"+user.getPassword());
        Users loginUser = new Users(100,user.getUsername(),user.getUsername());
        return loginUser;
    }

}

使用PostMan测试登录接口。效果完全一样。

2.@RequestBody

@RequestBody注解只拥有一个参数: required 默认为 true,即对象中的属性必须有一个要传,否则会抛出异常:org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing

@RequestBody注解获取的参数在请求哪? 1)post请求的requestHeaders请求头中有content-type字段,一般用来处理:applicatin/json格式的参数;注意:@RequestBody不能使用get请求! 2)Spring中的@RequestBody注解是用来接收请求体中的参数数据,即requestBody请求体中,故不受参数数据长度的限制; 3) 通常有适用于持续性作用,例如:对数据库添加、更新、删除等操作;

以上一节用户注册为例,使用@RequestBody接收注册表单数据。

package com.controller;

import com.entity.Users;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("users")
public class UsersController {

    @PostMapping(value="")
    public Users add(@RequestBody Users user){
        System.out.println("执行用户注册或者添加新用户....");
        System.out.println("新增用户资料:"+user);
        return user;
    }

}

使用PostMan测试注册接口。

服务器控制台输出结果如下:

执行用户注册或者添加新用户....
新增用户资料:Users{uid=0, username='admin', password='123456', salary=5000, gender='M', education=0, birthday='1999-10-01', favorites=[music, read], introduce='程序猿', province='陕西', accept='yes'}

3.关于http请求的相关知识

Http协议常用的四种请求方式:Post、Get、Put、Delete等;其中Put、Delete请求方式很少见,都可用Post方式代替。

1)对数据库而言: get 请求不修改数据库,只是查询。Post是增加记录,put是更新,Delete数据库删除; 2)Put,Post,Delete 方式的请求参数会直接放在requestBody里; 3)处理 request uri 部分的注解,路径参数变量:@PathVariable; 4)处理request header部分的注解: @RequestHeader, @CookieValue,@RequestParam; 5)处理request body部分的注解:@RequestParam, @RequestBody;  

综上所述:@RequestParam注解既可以接收Get方式的请求头中的参数,也可以接收Post方式的请求体中的参数;

get请求的 headers 中没有 content-type 这个字段,post请求有content-type字段,content-type类型有 :

1)application/x-www-form-urlencoded 这种就是一般的文本表单用 post 传地数据,只要将得到的 data 用 @RequestParam 或 request.getParamter() 获取即可; 2)multipart/form-data ,用于文件上传,此时 form 的 enctype 属性必须指定为 multipart/form-data; 3)application/json,将数据以json对象的格式传递; 4)text/xml; 5)put 和 delete 请求的headers 是有 content-type 这个字段的,只不过这两个方法类型目前不常用;