Fork me on GitHub

SpringMVC学习5-请求对象

Spring MVC

SpringMVC是基于MVC思想的JAVA WEB实现框架,是Spring家族的一员,它基于前置控制器来接收并分发请求,支持参考验证、请求参数封装、拦截、Restful等功能,是目前较为流行的MVC框架

本系列学习笔记包含如下的课程内容:

  • MVC思想
  • Hello案例
  • 请求和响应处理
  • 文件上传和下载处理
  • 参数验证
  • 请求拦截
  • RESTful风格
  • 日志

Request
框架的本质是对重复代码抽象,改为自动化执行。
对于浏览器提交给服务器的request请求,使用框架提供的便捷功能,可以显著提高开发效率。
常用配置如下:

@RequestParam

位置:方法参数前
作用:自动接收并和转换 request 中的参数

用法1:使用map接收所有参数

1
2
3
4
5
6
7
8
@RequestMapping("/demo1")
public String demo1map(@RequestParam Map<String, String> params) {
String name = params.get("name");
String age = params.get("age");
System.out.println("name:" + name);
System.out.println("age:" + age);
return "result1";
}

将所有参数封装在 map 中,
有效降低 request.getParameter("xxx") 的代码量。

用法2:逐个接收参数

1
2
3
4
5
6
@RequestMapping("/demo1")
public String test1(@RequestParam String name, @RequestParam int age) {
System.out.println("name:" + name);
System.out.println("age:" + age);
return "result1";
}

不用写 request.getParameter("xxx")
同时还能提供自动类型转换。
参数数量较多时,写起来不便。

对象接收参数

当请求中参数数量较多时,推荐使用。

提供一个 User 自定义类来进行封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class User {

private String name;
private String password;

public User() {
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}
}

form提交参数

在 form 表单中提交 user 对象, 参数名直接写 User 类的属性名

1
2
3
4
5
6
7
<form method="post" action="${path}/request/demo2">
Name:<input type="text" name="name" value="Test Name">
<br/>
Password:<input type="text" name="password" value="Test Pwd">
<br/>
<input type="submit" value="提交 user">
</form>

控制器接收

1
2
3
4
5
6
@RequestMapping("/demo2")
public String demo2(User user, Model model) {
System.out.println(user);
model.addAttribute("user", user);
return "result2";
}

不用写 request.getParameter("xxx")
提供自动类型转换的同时。
还可以进一步省略代码:

FAQ

@RequestParam 请求参数名与方法参数名不一致

如果请求中的参数名,与方法的参数名,不一致时.可以使用@RequestParam 的 value 属性来指定.
比如:

1
@RequestParam("myAge") int age

此时,请求请求参数 myAge ,对应到方法的参数 age

@RequestParam 针对请求中的参数不是必须的情况

设置 required 属性为 false即可.
比如:

1
@RequestParam(required = false) String name

如果请求中有指定的参数,就自动接收和转换; 如果请求中没有指定参数,也不会抛异常.

使用对象来接收参数时, 请求提交的参数数量,与封装类属性数量不一致

SpringMVC 仅替开发者自动实例化一个封装类的实例.即使 request 请求只提交了一个参数,而对应到的封装类有很多属性,SpringMVC 也还是会实例化对象,将这个参数写入对应属性.保留其他属性为默认值!

使用对象来接收参数时, 提交了多个对象的信息

比如:一个 form 表单,同时提交了 user 和 address 的信息,
可以考虑对多个对象进行封装,提供一个 Dto(Data Transfer Object,数据传递对象) 封装类:

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
import com.tz.entity.Address;
import com.tz.entity.User;

/**
* Data Transfer Object
*/
public class UserAddressDto {

private User user;
private Address address;

public UserAddressDto() {
}

public User getUser() {
return user;
}

public void setUser(User user) {
this.user = user;
}

public Address getAddress() {
return address;
}

public void setAddress(Address address) {
this.address = address;
}
}

在 form 表单中,注意参数名的写法,是以 UserAddressDto 为根开始写.

1
2
3
4
5
6
7
8
9
10
11
<form action="${path}/request/demo4" method="post">
用户-姓名:<input type="text" name="user.name"/>
<br/>
用户-年龄:<input type="text" name="user.age"/>
<br/>
地址-邮编:<input type="text" name="address.zipCode"/>
<br/>
地址-位置:<input type="text" name="address.location"/>
<br/>
<button type="submit">提交</button>
</form>

在控制器中,以 UserAddressDto 接收即可:

1
2
3
4
5
6
@RequestMapping(value = "/demo4")//将一个URL路径映射到当前类来处理
public String demo4(UserAddressDto userDto, Model model) throws UnsupportedEncodingException {
System.out.println("userDto:" + userDto);
model.addAttribute("userDto", userDto);
return "/WEB-INF/jsp/result4.jsp"; //默认就是 forward
}