SpringMVC接收前端参数为null的探索

SpringMVC接收前端参数为null的探索

在使用SpringMVC时接收前端参数有时后会无法封装,获得null值,报415错误的问题,原因就是有时候我们搞不懂json对象、json字符串、参数字符串之间的区别。

  • 提交方式:form/url,ajax

  • 请求方式:get,post

  • 接收方式:一个个参数接收,封装实体类(Bean类型)

文章将会排列组合= =,举例说明各种搭配如何成功接收数据。


form/url + get + 一个个接收/Bean类型

get请求基本没有什么坑,controller层一个个接和用实体类接都没有问题

html

1
2
3
4
5
6
<form action="testGet">
单个<input type="text" name="a"><br>
姓名:<input type="text" name="username"><br>
年龄:<input type="text" name="age"><br>
<input type="submit" value="提交">
</form>

controller

1
2
3
4
5
6
7
@RequestMapping("/testGet")
public String testGet(int a, User user){
System.out.println("testGet方法执行了");
System.out.println(a);
System.out.println(user);
return "success";
}

正常接收.png


form + post + 字符串类型

用一整个String body接收

html

1
2
3
4
5
<form action="testPostString" method="post">
姓名<input type="text" name="username" /><br>
年龄<input type="text" name="age" /><br>
<input type="submit" value="提交" />
</form>

controller

1
2
3
4
5
6
@RequestMapping("/testPostString")
public String testPostString(@RequestBody String body){
System.out.println("testPostString方法执行了");
System.out.println(body);
return "success";
}

可以看到form表单发送的数据格式

89wFzV.png

这种类似于get请求时发送url格式的参数我称为“参数字符串”,用一个String body接收是没问题的。就是麻烦了一点,需要接收后再处理成json对象


form + post + Bean类型

这个组合获取不到值会报415,就是类型不匹配(String和User),解决方法是在controller方法的参数上加@ModelAttribute注解

html

1
2
3
4
5
<form action="testPostBean" method="post">
姓名<input type="text" name="username" /><br>
年龄<input type="text" name="age" /><br>
<input type="submit" value="提交" />
</form>

controller

1
2
3
4
5
6
@RequestMapping("/testPostBean")
public String testPostBean(@ModelAttribute User user){
System.out.println("testPostBean方法执行了");
System.out.println(user);
return "success";
}

加了注解就可以自动封装

89wIyT.png


ajax + get/post + bean类型

异步的请求,发送给后台的就是两种:json或者json字符串,这个我觉得真的有点坑

这篇csdn博客写的很详细:https://blog.csdn.net/qq_37960007/article/details/79542727

根据这位博主的描述我直接给出这两种的写法,再做说明

两种可行办法
json字符串 + contentType指定为json + Bean接收
json对象 + contentType不指定 + Bean接收

法1

ajax

1
2
3
4
5
6
7
8
9
10
11
$.ajax({
url: "testAjax",
contentType: "application/json;charset=utf-8",
data:'{"username": "haha", "age": 20}',
dataType: "json",
type: "post",
success:function (data) {
alert(data);
alert(data.age);
}
});

controller

1
2
3
4
5
6
7
@RequestMapping("/testAjax")
public @ResponseBody User testAjax(@RequestBody User user){
System.out.println("testAjax方法执行了");
System.out.println(user);
user.setAge(100);
return user;
}

同时需要jackson的maven坐标

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.10.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.10.3</version>
</dependency>

效果如下,确实能接收(@ResponseBody注解是将User类变成json格式返回给前端,这个不是接收,不是我们要讨论的)

89fuu9.png


法2

ajax

1
2
3
4
5
6
7
8
9
10
$.ajax({
url: "testAjax2",
data:{"username": "haha", "age": 20},
dataType: "json",
type: "post",
success:function (data) {
alert(data);
alert(data.age);
}
});

controller

1
2
3
4
5
6
7
@RequestMapping("/testAjax2")
public @ResponseBody User testAjax2(@ModelAttribute User user){
System.out.println("testAjax方法执行了");
System.out.println(user);
user.setAge(100);
return user;
}

也是可以的

区别在哪里?

  1. json字符串和json对象

89oAl8.png

你不要问那些键加不加双引号行不行,值加不加双引号行不行,其实都可以,但是如果你写的标准的话他们就相差一对单引号!

  1. 是否有contentType: "application/json;charset=utf-8"

这个是指定发送给后台的类型,如果指定了json,那么说明:应该写json字符串,因为它会自动帮你转换这个字符串

如果没指定,则应该直接写json对象,因为它不会帮你转换,别弄反了

  1. controller层的区别

如果是用json字符串,那么controller就应该导入jackson的jar包,通过它来帮助我们完成映射

如果是用json对象,那么controller就使用@ModelAttribute,情况就行普通post的Bean封装


真的是天坑!!!!

ps:json对象 -> json字符串可以通过字符串的拼接或者JSON.stringify()

​ json字符串 -> json对象可以手动去除字符串或者JSON.parse()


axios + post + 字符串/bean类型

使用axios工具,如果发送post请求,且不用url拼接字符串的方式,而是试图发送整个json对象,如下

那么需要借助上面图中这样的qs工具,只需要在main.js(也可以随便找个全局的js文件)引入这个工具

NNjLIf.png

这样就可以像上面图示那样发送整个对象了,后台能接到

#
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×