Spring MVC 数据接收
# Spring MVC 数据接收
注解中的value参数作用
value
参数作用:指定前端传递的参数名称。当value
参数值与前端传递的参数名一致时,后端方法的参数名可以任意设置,不必与前端保持一致。- 简写形式:可以使用简写形式如
@RequestParam("id")
直接指定参数名。 - 默认映射规则:若不设置
value
参数,Spring默认使用方法参数名与前端参数名进行映射,此时方法参数名必须与前端传参名称完全一致。
# 1. 使用@RequestParam注解接收查询参数
注解功能:@RequestParam
注解用于接收HTTP请求中的查询参数或表单数据,将URL查询字符串或表单中的参数绑定到控制器方法的参数上。
重要配置参数:
value
:指定要绑定的请求参数名称required
:设置参数是否必须提供,默认为true
defaultValue
:为可选参数提供默认值
前端请求示例:
// 使用Axios发送GET请求并携带参数
axios.get('/api/getUser', {
params: {
id: 123, // 用户ID参数
name: '张三' // 用户姓名参数
}
})
.then(response => {
console.log('服务器返回数据:', response.data); // 处理服务器响应
})
.catch(error => {
console.error('请求发送失败:', error); // 处理请求错误
});
2
3
4
5
6
7
8
9
10
11
12
13
后端接收参数示例:
@RestController
@RequestMapping("/api")
public class UserController {
@GetMapping("/getUser")
public ResponseEntity<String> getUser(
@RequestParam(value = "id", required = true) int id, // 必填参数id,绑定前端传递的id参数
@RequestParam(value = "name", required = false, defaultValue = "匿名用户") String name // 可选参数name,未提供时使用默认值
) {
// 构建响应数据
String response = "接收到的用户信息 - ID: " + id + ", 姓名: " + name;
// 返回HTTP 200状态码和响应数据
return ResponseEntity.ok(response);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
关键点说明:
@RequestParam
适用于从URL查询字符串、表单数据中提取参数value
属性指定要绑定的参数名,是该注解的核心属性- 当
required=true
(默认值)时,如果请求中缺少该参数会返回400错误 defaultValue
属性允许为可选参数设置默认值,避免空值处理逻辑- 注解会自动进行类型转换,如字符串转数字,但转换失败会返回400错误
# 2. 使用@PathVariable注解接收URL路径参数
注解功能:@PathVariable
注解用于从URL路径中提取变量值,是实现RESTful API的重要工具,常用于资源定位,如/users/{id}
。
重要配置参数:
value
:指定路径变量名称,通常与URL模板中的占位符名称相同required
:指定路径变量是否必须存在,默认为true
前端请求示例:
// 使用Axios发送包含路径参数的GET请求
axios.get('/api/user/123') // 路径中123为用户ID
.then(response => {
console.log('服务器返回数据:', response.data); // 处理返回的用户数据
})
.catch(error => {
console.error('请求发送失败:', error); // 错误处理
});
2
3
4
5
6
7
8
后端接收参数示例:
@RestController
@RequestMapping("/api")
public class UserController {
@GetMapping("/user/{id}") // URL模板中使用{id}占位符表示路径变量
public ResponseEntity<String> getUserById(
@PathVariable(value = "id") int id // 从URL路径中提取id变量值并转换为int类型
) {
// 根据路径中的id查询用户信息(示例中仅返回id)
String response = "根据路径参数获取的用户ID: " + id;
// 返回HTTP 200状态码和响应数据
return ResponseEntity.ok(response);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
关键点说明:
@PathVariable
是RESTful API的核心组件,用于从URL路径中提取动态部分- 路径模板中的占位符(如
{id}
)必须与@PathVariable
的value
属性值匹配 - 与
@RequestParam
类似,Spring会自动进行类型转换 - 路径变量通常用于标识资源,如用户ID、产品ID等
- 与查询参数相比,路径变量更适合表示必要的、用于定位资源的参数
# 3. 使用@RequestBody注解接收JSON数据
注解功能:@RequestBody
注解用于接收HTTP请求体中的JSON数据并自动转换为Java对象,主要用于处理POST、PUT等请求中的JSON格式数据。
重要配置参数:
required
:指定请求体是否必须存在,默认为true
,设为false
时允许请求体为空
前端请求示例:
// 使用Axios发送POST请求,传递JSON格式数据
axios.post('/api/saveUser', {
id: 123, // 用户ID
name: '张三', // 用户姓名
age: 25 // 用户年龄
})
.then(response => {
console.log('保存成功,服务器响应:', response.data); // 处理保存成功的响应
})
.catch(error => {
console.error('用户数据保存失败:', error); // 处理保存失败的情况
});
2
3
4
5
6
7
8
9
10
11
12
后端接收参数示例:
@RestController
@RequestMapping("/api")
public class UserController {
@PostMapping("/saveUser")
public ResponseEntity<String> saveUser(
@RequestBody User user // 将请求体中的JSON数据反序列化为User对象
) {
// 处理接收到的用户数据(示例中仅构建响应字符串)
String response = "成功保存用户数据: " + user.toString();
// 返回HTTP 200状态码和响应信息
return ResponseEntity.ok(response);
}
}
// 用户数据模型类
class User {
private int id; // 用户ID
private String name; // 用户姓名
private int age; // 用户年龄
// 必须提供getter和setter方法,供Jackson进行JSON转换使用
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "ID: " + id + ", 姓名: " + name + ", 年龄: " + age;
}
}
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
关键点说明:
@RequestBody
主要用于接收JSON格式的请求体数据- Spring使用Jackson或其他配置的JSON库自动进行JSON到Java对象的转换
- 数据绑定遵循松散匹配原则:
- 前端多余的字段会被忽略
- 缺少的字段会使用对应类型的默认值(如null、0等)
- 转换的Java类必须有对应的getter/setter方法或公共字段
- 在前后端分离架构中,这是最常用的数据传递方式
JSON数据映射规则
- 字段名称匹配原则:前端JSON中的字段名须与Java对象的属性名一致(通常是驼峰命名)
- 额外字段处理:如果JSON包含目标类中不存在的字段,这些字段会被忽略
- 字段缺失处理:如果JSON缺少目标类中的字段,这些字段会被赋予默认值(如
null
、0
等) - 类型转换:Spring会尝试进行合理的类型转换,如String→数字,String→日期等
# 4. 使用@RequestHeader注解接收HTTP请求头
注解功能:@RequestHeader
注解用于获取HTTP请求头中的参数值,如获取Authorization
、User-Agent
、Content-Type
等请求头信息。
重要配置参数:
value
:指定要获取的HTTP请求头名称required
:指定请求头是否必须存在,默认为true
defaultValue
:当请求头不存在且required=false
时使用的默认值
前端请求示例:
// 使用Axios发送携带自定义请求头的POST请求
axios.post('/api/secure/saveUser', {
id: 123,
name: '张三',
age: 25
}, {
headers: {
Authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' // JWT认证令牌
}
})
.then(response => {
console.log('保存成功,响应数据:', response.data);
})
.catch(error => {
console.error('请求失败:', error);
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
后端接收参数示例:
@RestController
@RequestMapping("/api/secure")
public class UserController {
@PostMapping("/saveUser")
public ResponseEntity<String> saveUserWithAuth(
@RequestBody User user, // 接收请求体中的用户数据
@RequestHeader(value = "Authorization", required = false, defaultValue = "") String authToken // 获取Authorization请求头
) {
// 验证认证令牌
if (authToken.isEmpty()) {
// 如果令牌为空,返回401未授权状态码
return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
.body("未提供有效的认证令牌,无法保存用户数据");
}
// 验证通过,处理用户数据
String response = "已授权保存用户数据: " + user.toString() +
"\n使用的认证令牌: " + authToken;
// 返回成功响应
return ResponseEntity.ok(response);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
关键点说明:
@RequestHeader
专用于获取HTTP请求头中的值- 常用于获取认证信息、客户端信息、内容协商相关头等
- 与其他参数注解一样,支持类型转换
- 可以设置为非必须并提供默认值,增加API的健壮性
- 在实现认证、跨域、缓存控制等功能时特别有用
# 5. 使用@ModelAttribute注解接收表单数据
使用场景说明
在现代前后端分离的Web应用中,表单数据通常以JSON格式提交,但某些场景(如文件上传)仍需使用传统表单格式,因此了解@ModelAttribute
的使用方法仍然重要。
注解功能:@ModelAttribute
用于绑定表单数据到方法参数对象,处理application/x-www-form-urlencoded
或multipart/form-data
格式的请求数据。
重要配置参数:
value
:指定绑定的数据名称(一般不常用)binding
:控制是否执行数据绑定,默认为true
前端请求示例:
// 使用Axios模拟传统表单提交
// URLSearchParams会将数据格式化为application/x-www-form-urlencoded格式
axios.post('/api/form/saveUser', new URLSearchParams({
id: 123, // 用户ID
name: '张三', // 用户姓名
age: 25 // 用户年龄
}))
.then(response => {
console.log('表单提交成功:', response.data);
})
.catch(error => {
console.error('表单提交失败:', error);
});
2
3
4
5
6
7
8
9
10
11
12
13
后端接收参数示例:
@RestController
@RequestMapping("/api/form")
public class UserController {
@PostMapping("/saveUser")
public ResponseEntity<String> saveUserForm(
@ModelAttribute User user // 将表单数据绑定到User对象
) {
// 处理接收到的表单数据
String response = "已接收表单数据并保存用户: " + user.toString();
// 返回成功响应
return ResponseEntity.ok(response);
}
}
// 用户数据类定义(与前面示例相同)
class User {
private int id; // 用户ID
private String name; // 用户姓名
private int age; // 用户年龄
// getter和setter方法(必须提供)
// ...
@Override
public String toString() {
return "ID: " + id + ", 姓名: " + name + ", 年龄: " + age;
}
}
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
关键点说明:
@ModelAttribute
主要用于处理传统表单提交的数据- 表单字段名必须与Java对象的属性名一致
- 与
@RequestBody
不同,它处理的是application/x-www-form-urlencoded
和multipart/form-data
格式 - 在文件上传表单中特别有用,可以同时接收普通字段和文件字段
- 尽管在前后端分离应用中使用较少,但在某些场景下仍然重要(如文件上传)
# 6. 使用MultipartFile处理单文件上传
功能说明:MultipartFile
是Spring MVC提供的文件处理接口,通过@RequestParam
注解绑定上传的文件,主要用于处理表单中的文件上传。
前端请求示例:
// 使用Axios发送包含文件的表单请求
// 假设已通过input元素选择了文件
let formData = new FormData();
formData.append('file', this.selectedFile); // 添加文件到FormData对象
// 发送包含文件的POST请求
axios.post('/api/upload/single', formData, {
headers: {
'Content-Type': 'multipart/form-data' // 设置正确的内容类型
}
})
.then(response => {
console.log('文件上传成功:', response.data);
})
.catch(error => {
console.error('文件上传失败:', error);
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
后端接收文件示例:
@RestController
@RequestMapping("/api/upload")
public class FileUploadController {
@PostMapping("/single")
public ResponseEntity<String> uploadSingleFile(
@RequestParam("file") MultipartFile file // 接收名为"file"的上传文件
) {
// 检查文件是否为空
if (file.isEmpty()) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body("上传失败:未选择文件或文件为空");
}
// 获取文件原始名称
String fileName = file.getOriginalFilename();
// 构建文件保存路径
Path filePath = Paths.get("uploads/" + fileName);
try {
// 确保目标目录存在
Files.createDirectories(Paths.get("uploads/"));
// 将上传的文件保存到服务器
Files.copy(file.getInputStream(), filePath, StandardCopyOption.REPLACE_EXISTING);
// 返回成功信息
return ResponseEntity.ok("文件上传成功: " + fileName +
"\n文件大小: " + file.getSize() + " 字节" +
"\n文件类型: " + file.getContentType());
} catch (IOException e) {
// 处理文件保存过程中的异常
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("文件上传过程中发生错误: " + e.getMessage());
}
}
}
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
37
38
关键点说明:
- 前端必须使用
FormData
对象构建multipart请求 - 设置正确的
Content-Type: multipart/form-data
头部 - 后端使用
@RequestParam
注解和MultipartFile
类型接收文件 MultipartFile
接口提供了访问文件内容、名称、大小的方法- 通常需要进行文件类型验证、大小限制等安全检查
- 应当添加异常处理来应对文件操作的各种问题
# 7. 使用List<MultipartFile>处理多文件上传
功能说明:Spring MVC支持通过List<MultipartFile>
或MultipartFile[]
接收多个上传文件,适用于需要一次上传多个文件的场景。
前端请求示例:
// 使用Axios发送多文件上传请求
let formData = new FormData();
// 假设this.selectedFiles是一个包含多个File对象的数组
this.selectedFiles.forEach(file => {
formData.append('files', file); // 使用相同的键名'files'添加多个文件
});
// 发送包含多个文件的POST请求
axios.post('/api/upload/multiple', formData, {
headers: {
'Content-Type': 'multipart/form-data' // 设置multipart格式
}
})
.then(response => {
console.log('多文件上传成功:', response.data);
})
.catch(error => {
console.error('多文件上传失败:', error);
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
后端接收文件示例:
@RestController
@RequestMapping("/api/upload")
public class FileUploadController {
@PostMapping("/multiple")
public ResponseEntity<String> uploadMultipleFiles(
@RequestParam("files") List<MultipartFile> files // 接收多个文件
) {
// 检查是否有文件被上传
if (files.isEmpty()) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body("上传失败:未选择任何文件");
}
// 创建一个列表存储成功上传的文件名
List<String> fileNames = new ArrayList<>();
// 创建目标目录
try {
Files.createDirectories(Paths.get("uploads/"));
} catch (IOException e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("创建上传目录失败: " + e.getMessage());
}
// 遍历处理每个文件
for (MultipartFile file : files) {
// 跳过空文件
if (file.isEmpty()) {
continue;
}
// 获取文件名
String fileName = file.getOriginalFilename();
Path filePath = Paths.get("uploads/" + fileName);
try {
// 保存文件到服务器
Files.copy(file.getInputStream(), filePath, StandardCopyOption.REPLACE_EXISTING);
fileNames.add(fileName);
} catch (IOException e) {
// 如果某个文件保存失败,返回错误信息
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("上传过程中发生错误,部分文件可能未保存成功: " + e.getMessage());
}
}
// 构建包含所有成功上传文件的响应信息
StringBuilder response = new StringBuilder("成功上传 ")
.append(fileNames.size())
.append(" 个文件:\n");
for (String fileName : fileNames) {
response.append("- ").append(fileName).append("\n");
}
// 返回成功响应
return ResponseEntity.ok(response.toString());
}
}
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
关键点说明:
- 前端使用相同的参数名多次调用
formData.append()
添加多个文件 - 后端使用
List<MultipartFile>
接收多个文件,比数组更灵活 - 需要单独处理每个文件的保存和错误情况
- 建议实施的安全措施:
- 限制上传文件总数
- 限制单个文件和所有文件的总大小
- 验证文件类型
- 重命名文件以防止覆盖和路径遍历攻击
# 8. 使用@CookieValue注解接收Cookie数据
注解功能:@CookieValue
注解用于从请求中获取指定名称的Cookie值,常用于获取会话标识、用户偏好等存储在客户端的数据。
重要配置参数:
value
:指定要获取的Cookie名称required
:指定Cookie是否必须存在,默认为true
defaultValue
:当Cookie不存在且required=false
时使用的默认值
前端请求示例:
// 浏览器会自动发送相关域的Cookie,无需特殊处理
axios.get('/api/user/profile')
.then(response => {
console.log('获取到用户资料:', response.data);
})
.catch(error => {
// 可能因未登录(无Cookie)而失败
console.error('获取用户资料失败:', error);
});
2
3
4
5
6
7
8
9
后端接收Cookie示例:
@RestController
@RequestMapping("/api/user")
public class UserController {
@GetMapping("/profile")
public ResponseEntity<String> getUserProfile(
@CookieValue(value = "sessionId", required = false, defaultValue = "未登录") String sessionId // 获取名为sessionId的Cookie
) {
// 检查会话标识是否为默认值
if ("未登录".equals(sessionId)) {
// 用户未登录,返回401未授权状态
return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
.body("您尚未登录,请先登录后再访问个人资料");
}
// 正常情况,根据会话ID查询用户资料
// 这里简化处理,实际应用中会根据sessionId从数据库或缓存获取用户信息
String userDetails = "根据会话ID(" + sessionId + ")获取的用户资料:\n" +
"- 用户名: 张三\n" +
"- 邮箱: zhangsan@example.com\n" +
"- 会员等级: 黄金会员";
// 返回用户资料
return ResponseEntity.ok(userDetails);
}
}
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
关键点说明:
- Cookie由浏览器自动发送,前端通常不需要特殊处理
@CookieValue
用于直接获取特定名称的Cookie值- 可以设置为非必须并提供默认值,增强API健壮性
- 常用于获取会话标识、用户偏好、跟踪标识等
- 在处理认证相关功能时特别有用
# 9. 使用@SessionAttribute注解接收Session属性
注解功能:@SessionAttribute
注解用于从HttpSession中直接获取特定属性,简化了对会话数据的访问,常用于获取登录用户信息等会话状态。
前端请求示例:
// 前端发送普通请求,服务器会通过会话Cookie关联到对应的Session
axios.get('/api/session/getUserInfo')
.then(response => {
console.log('从会话中获取的用户信息:', response.data);
})
.catch(error => {
console.error('获取会话信息失败:', error);
});
2
3
4
5
6
7
8
后端接收Session属性示例:
@RestController
@RequestMapping("/api/session")
public class SessionController {
// 设置会话属性的方法(通常由登录接口调用)
@PostMapping("/setUserInfo")
public ResponseEntity<String> setUserInfo(HttpSession session) {
// 向会话中存储用户信息
session.setAttribute("username", "张三");
session.setAttribute("userId", 12345);
session.setAttribute("userRole", "ADMIN");
// 返回成功信息
return ResponseEntity.ok("用户信息已成功保存到会话中");
}
// 获取会话属性的方法
@GetMapping("/getUserInfo")
public ResponseEntity<String> getUserInfo(
@SessionAttribute(value = "username", required = false) String username, // 获取会话中的username属性
@SessionAttribute(value = "userId", required = false) Integer userId, // 获取会话中的userId属性
@SessionAttribute(value = "userRole", required = false) String userRole // 获取会话中的userRole属性
) {
// 检查用户是否已登录(会话中是否有用户名)
if (username == null) {
// 用户未登录,返回401未授权状态
return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
.body("未找到会话中的用户信息,请先登录");
}
// 构建包含会话信息的响应
StringBuilder response = new StringBuilder("会话中的用户信息:\n");
response.append("- 用户名: ").append(username).append("\n");
// 添加用户ID(如果存在)
if (userId != null) {
response.append("- 用户ID: ").append(userId).append("\n");
}
// 添加用户角色(如果存在)
if (userRole != null) {
response.append("- 用户角色: ").append(userRole).append("\n");
}
// 返回会话信息
return ResponseEntity.ok(response.toString());
}
}
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
37
38
39
40
41
42
43
44
45
46
47
48
关键点说明:
@SessionAttribute
简化了从HttpSession中获取特定属性的操作- 可以指定
required=false
使属性变为可选 - 相比直接注入HttpSession对象更加简洁高效
- 适合从会话中获取已知属性(如用户标识、权限等)
- 注意:在分布式系统中使用Session需要特别考虑会话同步问题
# 10. 使用@DateTimeFormat注解处理日期参数
注解功能:@DateTimeFormat
注解用于定义日期字符串的解析格式,将前端传递的日期字符串转换为Java日期对象。
重要配置参数:
pattern
:指定日期格式模式,如yyyy-MM-dd
、yyyy-MM-dd HH:mm:ss
等
前端请求示例:
// 发送包含日期参数的GET请求
axios.get('/api/getUserByDate', {
params: {
birthDate: '2000-01-15' // 日期格式为yyyy-MM-dd
}
})
.then(response => {
console.log('按出生日期查询结果:', response.data);
})
.catch(error => {
console.error('查询失败:', error);
});
2
3
4
5
6
7
8
9
10
11
12
后端接收日期参数示例:
@RestController
@RequestMapping("/api")
public class UserController {
@GetMapping("/getUserByDate")
public ResponseEntity<String> getUserByDate(
@RequestParam("birthDate")
@DateTimeFormat(pattern = "yyyy-MM-dd") Date birthDate // 指定日期格式并转换为Date对象
) {
// 日期格式化工具,用于格式化输出
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
// 使用日期参数查询用户(示例中简化为直接返回日期信息)
String response = "已接收出生日期参数: " + sdf.format(birthDate) +
"\n查询结果: 找到5名用户出生于该日期";
// 返回响应结果
return ResponseEntity.ok(response);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
关键点说明:
@DateTimeFormat
注解需要与参数注解(如@RequestParam
)一起使用pattern
属性定义了日期字符串的预期格式- 如果前端传递的日期格式与指定的pattern不匹配,会发生解析错误
- 支持各种日期时间格式,可以精确到年月日或精确到毫秒
- 适用于GET请求中的查询参数、表单字段等
# 11. 在对象属性中使用@DateTimeFormat注解处理日期
功能说明:当Java对象中包含日期类型属性时,可以在属性上使用@DateTimeFormat
注解来指定日期格式,使Spring能够正确解析前端传来的日期字符串。
前端请求示例:
// 发送包含日期字段的JSON数据
axios.post('/api/saveUser', {
userName: '张三',
birthDate: '2000-01-15', // 日期格式为yyyy-MM-dd
registrationTime: '2023-08-17 14:30:00' // 日期时间格式为yyyy-MM-dd HH:mm:ss
})
.then(response => {
console.log('用户保存成功:', response.data);
})
.catch(error => {
console.error('用户保存失败:', error);
});
2
3
4
5
6
7
8
9
10
11
12
后端对象和接收示例:
// 用户数据模型类
class User {
private String userName; // 用户名
@DateTimeFormat(pattern = "yyyy-MM-dd") // 指定日期格式
private Date birthDate; // 出生日期
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") // 指定日期时间格式
private Date registrationTime; // 注册时间
// Getter和Setter方法(必须提供)
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
public Date getRegistrationTime() {
return registrationTime;
}
public void setRegistrationTime(Date registrationTime) {
this.registrationTime = registrationTime;
}
}
@RestController
@RequestMapping("/api")
public class UserController {
@PostMapping("/saveUser")
public ResponseEntity<String> saveUser(@RequestBody User user) {
// 日期格式化工具
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日");
SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
// 构建响应信息
StringBuilder response = new StringBuilder("用户信息保存成功:\n");
response.append("- 用户名: ").append(user.getUserName()).append("\n");
// 格式化输出日期
if (user.getBirthDate() != null) {
response.append("- 出生日期: ").append(dateFormat.format(user.getBirthDate())).append("\n");
}
// 格式化输出日期时间
if (user.getRegistrationTime() != null) {
response.append("- 注册时间: ").append(dateTimeFormat.format(user.getRegistrationTime())).append("\n");
}
// 返回响应
return ResponseEntity.ok(response.toString());
}
}
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
关键点说明:
- 在实体类的日期属性上直接使用
@DateTimeFormat
注解 - 每个日期属性可以指定不同的格式模式
- 当使用
@RequestBody
接收JSON数据时,Spring会根据注解自动解析日期字符串 - Java 8中也可以使用
LocalDate
、LocalDateTime
等新日期API类型 - 前端必须确保发送的日期格式与后端定义的格式一致
# 12. 接收数组或集合类型参数
# 前端发送数组或集合参数
注解功能:Spring MVC支持接收数组或集合类型的参数,可以通过URL查询参数或JSON数据传递。
前端GET请求发送数组示例:
// 使用GET请求发送数组参数(查询参数形式)
axios.get('/api/getItems', {
params: {
ids: [1, 2, 3, 4, 5] // 数组参数
}
})
.then(response => {
console.log('查询结果:', response.data);
})
.catch(error => {
console.error('查询失败:', error);
});
// 实际发送的URL:/api/getItems?ids=1&ids=2&ids=3&ids=4&ids=5
2
3
4
5
6
7
8
9
10
11
12
13
14
前端POST请求发送数组示例:
// 使用POST请求发送包含数组的JSON数据
axios.post('/api/saveItems', {
ids: [1, 2, 3, 4, 5], // 数字数组
tags: ['促销', '新品', '限时'], // 字符串数组
name: '商品批量操作' // 普通字段
})
.then(response => {
console.log('保存成功:', response.data);
})
.catch(error => {
console.error('保存失败:', error);
});
2
3
4
5
6
7
8
9
10
11
12
# 后端接收数组或集合参数
1. 使用@RequestParam
接收GET请求中的数组参数
@RestController
@RequestMapping("/api")
public class ItemController {
@GetMapping("/getItems")
public ResponseEntity<String> getItems(
@RequestParam List<Integer> ids // 直接接收数组参数为List<Integer>
) {
// 检查参数是否为空
if (ids == null || ids.isEmpty()) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body("请至少提供一个商品ID");
}
// 构建响应数据(实际应用中通常会查询数据库)
StringBuilder response = new StringBuilder("根据ID查询到以下商品:\n");
for (Integer id : ids) {
response.append("- ID: ").append(id)
.append(", 商品名称: 商品").append(id)
.append(", 价格: ").append(id * 10).append(".00元\n");
}
// 返回响应结果
return ResponseEntity.ok(response.toString());
}
}
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
2. 使用@RequestBody
接收POST请求中的数组或集合参数
@RestController
@RequestMapping("/api")
public class ItemController {
@PostMapping("/saveItems")
public ResponseEntity<String> saveItems(
@RequestBody ItemBatchOperation operation // 接收整个JSON对象
) {
// 验证数据
if (operation.getIds() == null || operation.getIds().isEmpty()) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body("请至少提供一个商品ID");
}
// 构建响应信息
StringBuilder response = new StringBuilder("批量操作成功:\n");
response.append("- 操作名称: ").append(operation.getName()).append("\n");
response.append("- 处理的商品ID: ").append(operation.getIds()).append("\n");
// 如果有标签,也添加到响应中
if (operation.getTags() != null && !operation.getTags().isEmpty()) {
response.append("- 应用的标签: ").append(operation.getTags()).append("\n");
}
// 返回操作结果
return ResponseEntity.ok(response.toString());
}
}
// 接收批量操作数据的模型类
class ItemBatchOperation {
private List<Integer> ids; // 商品ID列表
private List<String> tags; // 标签列表
private String name; // 操作名称
// Getter和Setter方法
public List<Integer> getIds() {
return ids;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
public List<String> getTags() {
return tags;
}
public void setTags(List<String> tags) {
this.tags = tags;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
3. 直接接收数组类型参数
除了使用集合类型外,也可以直接使用数组类型接收参数:
@RestController
@RequestMapping("/api")
public class ItemController {
@GetMapping("/getItemsByArray")
public ResponseEntity<String> getItemsByArray(
@RequestParam Integer[] ids // 使用数组而非List接收参数
) {
// 检查参数
if (ids == null || ids.length == 0) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body("请至少提供一个商品ID");
}
// 构建响应
StringBuilder response = new StringBuilder("使用数组接收到以下ID:\n");
for (Integer id : ids) {
response.append("- ").append(id).append("\n");
}
return ResponseEntity.ok(response.toString());
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
数组与集合参数处理要点
- GET请求中的数组参数:
- 前端:Axios会自动将数组参数格式化为形如
?ids=1&ids=2&ids=3
的查询字符串 - 后端:可以使用
List<T>
或T[]
接收,Spring会自动进行类型转换
- 前端:Axios会自动将数组参数格式化为形如
- POST请求中的JSON数组:
- 前端:直接在JSON对象中包含数组字段
- 后端:使用
@RequestBody
将整个JSON反序列化为对象,对象中使用List<T>
或T[]
接收数组字段
- 类型转换:
- Spring会自动尝试将字符串转换为目标类型(整数、日期等)
- 转换失败会导致请求错误,应妥善处理异常
- 空值处理:
- 应检查接收到的数组或集合是否为空,并给出适当的响应