在使用SpringMVC时接收前端参数有时后会无法封装,获得null值,报415错误 的问题,原因就是有时候我们搞不懂json对象、json字符串、参数字符串之间的区别。
文章将会排列组合= =,举例说明各种搭配如何成功接收数据。
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" ; }
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表单发送的数据格式
这种类似于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" ; }
加了注解就可以自动封装
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格式返回给前端,这个不是接收,不是我们要讨论的)
法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; }
也是可以的
区别在哪里?
json字符串和json对象
你不要问那些键加不加双引号行不行,值加不加双引号行不行,其实都可以,但是如果你写的标准的话 他们就相差一对单引号!
是否有contentType: "application/json;charset=utf-8"
这个是指定发送给后台的类型,如果指定了json ,那么说明:应该写json字符串 ,因为它会自动帮你转换这个字符串
如果没指定 ,则应该直接写json对象 ,因为它不会帮你转换,别弄反了
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文件)引入这个工具
这样就可以像上面图示那样发送整个对象了,后台能接到