@RequestBody和@RequestParam的区别

先上代码,再说区别:

前端:

使用@RequestParam:主要处理contentType为application/x-www-form-urlencoded的数据(默认)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="/js/jquery-3.3.1.js"></script>
</head>
<body>
<input id="username" name="username"/>
<input type="password" id="password" name="password"/>
<input type="checkbox" id="rememberMe" name="rememberMe"/>
<button type="button">提交</button>
</body>
<script type="text/javascript">
    var obj = window.document.location;
    var BASE_PATH = obj.href.substring(0, obj.href.indexOf(obj.pathname));
    $("button").on("click", function () {
        var dataForm = {};
        var username = $("#username").val();
        var password = $("#password").val();
        dataForm.username = username;
        dataForm.password = password;
        $.ajax({
            url: BASE_PATH + "/test",
            type: "post",
            data:dataForm,
            success: function f(data) {
                
            }
        })
    });
</script>
</html>

使用@ResponseBody:主要处理contentType不为application/x-www-form-urlencoded的数据

在ajax中要指明contentType:"application/json;charset=UTF-8",data:JSON.stringify(json数组);

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="/js/jquery-3.3.1.js"></script>
</head>
<body>
<input id="username" name="username"/>
<input type="password" id="password" name="password"/>
<input type="checkbox" id="rememberMe" name="rememberMe"/>
<button type="button">提交</button>
</body>
<script type="text/javascript">
    var obj = window.document.location;
    var BASE_PATH = obj.href.substring(0, obj.href.indexOf(obj.pathname));
    $("button").on("click", function () {
        var dataForm = {};
        var username = $("#username").val();
        var password = $("#password").val();
        dataForm.username = username;
        dataForm.password = password;
        $.ajax({
            url: BASE_PATH + "/test",
            type: "post",
            contentType : "application/json;charset=UTF-8",
            data:JSON.stringify(dataForm),
            success: function f(data) {

            }
        })
    });
</script>
</html>

后端:

使用@RequestParam:要指明前端传过来的参数名并与其对应

@PostMapping("test")
public Object test(@RequestParam (value = "username") String username,
				   @RequestParam (value = "password") String password){
	System.out.println(username);
	System.out.println(password);
	return null;
}

使用@RequestBody:直接对象接收,属性名要与前端传过来的数据的key值对应

package com.example.demo.vo;

/**
 * @author FastKing
 * @version 1.0
 * @date 2018/10/10 13:54
 **/
public class TestVO {

	private String username;
	private String password;

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}
}
@PostMapping("test")
	public Object test(@RequestBody TestVO testVO){

		System.out.println(testVO.getUsername());
		System.out.println(testVO.getPassword());
		return null;
	}

按F12看一下Network里对应请求:

使用@RequestParam:Content-Type为application/x-www-form-urlencoded,参数在FormData中

使用@RequestBody:Content-Type为application/json,参数在Request PayLoad中

因为两个注解处理的数据的编码格式不同,ajax又不可能同时指定两个编码格式,所以一般情况下是不可以同时使用的;

如果一定要同时使用,在请求头上拼@RequestParam接收的参数,使用@RequestBody的那一套前端把对象传到后端,后端就能获取到了


上面已经讲了,可以使用多个@RequestParam获取数据,那么可以使用多个@RequestBody吗,现在上代码试一下:

前端:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="/js/jquery-3.3.1.js"></script>
</head>
<body>
<input id="username" name="username"/>
<input type="password" id="password" name="password"/>
<input type="checkbox" id="rememberMe" name="rememberMe"/>
<button type="button">提交</button>
</body>
<script type="text/javascript">
    var obj = window.document.location;
    var BASE_PATH = obj.href.substring(0, obj.href.indexOf(obj.pathname));
    $("button").on("click", function () {
        var dataForm = {};
        var username = $("#username").val();
        var password = $("#password").val();
        dataForm.username = username;
        dataForm.password = password;
        dataForm.usernameTwo = "rootTwo";
        dataForm.passwordTwo = "123456Two";
        $.ajax({
            url: BASE_PATH + "/test",
            type: "post",
            contentType : "application/json;charset=UTF-8",
            data:JSON.stringify(dataForm),
            success: function f(data) {

            }
        })
    });
</script>
</html>

后端:

VO类

package com.example.demo.vo;

/**
 * @author FastKing
 * @version 1.0
 * @date 2018/10/10 17:53
 **/
public class TestTwoVO {

	private String usernameTwo;

	private String passwordTwo;

	public String getUsernameTwo() {
		return usernameTwo;
	}

	public void setUsernameTwo(String usernameTwo) {
		this.usernameTwo = usernameTwo;
	}

	public String getPasswordTwo() {
		return passwordTwo;
	}

	public void setPasswordTwo(String passwordTwo) {
		this.passwordTwo = passwordTwo;
	}
}

 Controller

@PostMapping("test")
	public Object test(@RequestBody TestVO testVO, @RequestBody TestTwoVO testTwoVO) {

		System.out.println(testVO.getUsername());
		System.out.println(testVO.getPassword());
		System.out.println(testTwoVO.getUsernameTwo());
		System.out.println(testTwoVO.getPasswordTwo());
		return null;
	}

会报如下错误:

WARN 26532 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: I/O error while reading input message; nested exception is java.io.IOException: Stream closed

由于前端往后端传数据是以IO流的方式,而第一个@RequestBody在接收完自己的数据后,就把IO流关掉了,导致第二个@RequestBody无法再读取上一个IO流,所以@RequestBody不能在同一个方法中出现多次

猜你喜欢

转载自blog.csdn.net/weixin_39841589/article/details/82996051