Springmvc传参总结
我们前端向springmvc
进行传参的时候,主要是用到了以下三种方法:
- 使用表单来提交
ajax
使用formdata
发送
ajax
使用前端对象{..}
发送
使用表单
前端使用form表单进行提交,这样是最简单的方法,我们需要注意,如果我们没有设置@RequestParam
指定名称的话,我们接收的变量名要和前端发送的key
值相同。我们也可以让springmvc
自己把我们传入的key,value
绑定成已有对象,接下来进行实例:
jsp
1 2 3 4 5 6 7 8 9 10 11
| <form action="testDatePojo" method="post"> 姓名<input name="username" ><br> 密码<input name="password" ><br> 生日<input name="birthday" ><br> <input type="radio" name="gender" value="0">man<br> <input type="radio" name="gender" value="1">woman<br> <input type="checkbox" name="hobby" value="basketball">篮球<br> <input type="checkbox" name="hobby" value="football">足球<br> <input type="checkbox" name="hobby" value="badball">羽毛球<br> <input type="submit" value="pojosubmit"> </form>
|
pojo
这里使用了@DateTimeFormat
指定了我们日期的转换格式,其实springmvc
帮我们定义了一个日期转换器Convertor
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package com.zgy.springmvc.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.format.annotation.DateTimeFormat; import java.io.Serializable; import java.util.Date;
@Data @AllArgsConstructor @NoArgsConstructor public class User implements Serializable { private String username; private String password; @DateTimeFormat(pattern = "yyyy-MM-dd") private Date birthday; private String gender; private String[] hobby;
}
|
controller
1 2 3 4 5
| @RequestMapping("/testPojo") public String testPojo(User user){ System.out.println(user); return "success"; }
|
使用FormData
的时候,我们需要在后端加入传文件的两个依赖,配置CommonsMultipartResolver
这样springmvc
才能够正常解析。
1 2 3 4 5 6 7 8 9 10
| <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.11.0</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.4</version> </dependency>
|
jsp
需要注意的是我们前端ajax
需要加上以下两个参数,这个和传送文件一样。
1 2
| processData: false, // jQuery不要去处理发送的数据 contentType:false,
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| <%@page contentType="text/html;charset=UTF-8" %> <html> <head> <script src="js/jquery.min.js"></script> <script> let form_data = new FormData(); form_data.set("username","123"); form_data.set("password","123"); form_data.set("birthday","2022-12-01"); form_data.set("gender","1"); form_data.set("hobby","123");
let click1 = ()=>{ alert("123"); console.log(form_data); $.ajax({ type:"post", processData: false, contentType:false, url:"http://localhost:8080/springmvc_param_war_exploded/testPojo", data:form_data, success(res){ console.log(res); console.log("123123"); } });
}; </script> </head> <body> <button onclick="click1()">123</button> </body> </html>
|
controller
我们可以使用对象接收,包装。
1 2 3 4 5
| @RequestMapping("/testPojo") public String testPojo(User user){ System.out.println(user); return "success"; }
|
同样我们可以使用@RequestParam
来指定接收的参数
1 2 3 4 5
| @RequestMapping("/testPojo") public String testPojo(@RequestParam("username") String user){ System.out.println(user); return "success"; }
|
使用对象传输
我们在前端使用ajax
传输对象其实就是传输JSON格式的内容,其中我们的contentType
应该是application/json
,用来指名我们传输的是JSON文件。需要注意的是data
里面不能直接传输对象,我们需要JSON.stringfy()
将对象转换成JSON字符串格式,因为JSON其实是字符串不是对象。同样因为我们后端接收JSON转换成java
对象,同样用到了我们的jackson
,需要导入以下jar
包。
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.14.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.14.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.14.1</version> </dependency>
|
jsp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <%@page contentType="text/html;charset=UTF-8" %> <html> <head> <script src="js/jquery.min.js"></script> <script> let click1 = ()=>{ alert("123"); console.log(form_data); $.ajax({ type:"post", contentType:"application/json", dataType : 'json', url:"http://localhost:8080/springmvc_param_war_exploded/testJson", data:JSON.stringify({ "username":"张歌" }), success(res){ console.log(res); console.log("123123"); } }); }; </script> </head> <body> <button onclick="click1()">123</button> </body> </html>
|
controller
我们需要使用@RequestBody
注解,将我们传过来的JSON
数据转换成我们的java
对象,这个原理和@ResponseBody
一样。
1 2 3 4 5 6
| @ResponseBody @RequestMapping("/testJson") public String testPojo1(@RequestBody Map<String, String> requestBody){ System.out.println(requestBody); return "success"; }
|
我们同样可以转换成对象
1 2 3 4 5 6
| @ResponseBody @RequestMapping("/testJson") public String testPojo1(@RequestBody User requestBody){ System.out.println(requestBody); return "success"; }
|
总结
contentType 常见的格式
text/plain
:纯文本格式
application/json
: JSON数据格式
application/x-www-form-urlencoded
中默认的encType
,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)使用的是url 编码格式。
multipart/form-data
: 需要在表单中进行文件上传时,就需要使用该格式
form
非编码格式 - Multipart From
(文件流的格式)
contentType:false
的原因
由于 涉及文件上传,表单的 提交必须采取非编码格式 即,’content-type’:multipart/form-data;boundary=${boundary}
;${boundary}
为一分割字符串。但是,重点来了,ajax
只要主动设置 content-type
为multipart/form-data
,不加后面的boundary
,会自动加到传输的格式中,导致后端取不到值。如果加了boundary
,又导致直接formData
都取不到值。最终解决方案就是,content-type
不进行设置,只将data
改为 formData
格式。浏览器会自动识别,自动设置为content-type:multipart/form-data;boundary=随机值
的形式。最终上传成功。
processData: false
的原因
默认情况下,processData
的值是 true
,其代表以对象的形式上传的数据都会被转换为字符串的形式上传。而当上传文件的时候,则不需要把其转换为字符串,因此要改成false
,如果要用 ajax
上传文件,则需要使用 FormData
对象来作为数据,而不能使用 form
的 serialize
方法(原因是 serialize
方法得到的数据是一个字符串,其不支持二进制数据传输,因此无法上传文件)