文章目录
一.请求参数绑定
- 提交表单的name和参数的名称应相同
- 如果接收JavaBean则必须和JavaBean的属性名相同
- 区分大小写
1.基本数据类型和字符串类型
@Controller
@RequestMapping(value = "/user")
public class UserController {
/***
* 接收基本数据类型和String
* 此时可以访问 http://localhost:8080/user/add?id=9&name=小明
* 注意:此时请求地址的id和name和addUser(int id,String name)中的入参名字要一致才能接到参数。
* @return
*/
@RequestMapping(value = "/add")
public String addUser(int id,String name){
System.out.println("ID:"+id+",NAME:"+name);
return "success";
}
}
2.JavaBean类型
实体bean
public class User {
private String name;
private Integer age;
//get...set...
}
addUser方法
@Controller
@RequestMapping(value = "/user")
public class UserController {
/***
* 这里直接接收一个User 对象即可
* 注意:
* 页面表单需要和user对应的属性名字一致
* 姓名:<input name="name" /> name="name"和User的name属性名一样
* 年龄:<input name="age" /> name="age"和User的age属性名一样
* @return
*/
@RequestMapping(value = "/add")
public String addUser(User user){
System.out.println("AGE:"+user.getAge()+",NAME:"+user.getName());
return "success";
}
}
index.jsp准备表单
<form action="/user/add" method="post">
<div>
名字:<input name="name" >
</div>
<div>
年龄:<input name="age" >
</div>
<div>
<input type="submit" value="提交">
</div>
</form>
3.集合数据类型
3.1 Map
修改addUser,需要加上一个注解@RequestParam来接收Map数据
@Controller
@RequestMapping(value = "/user")
public class UserController {
/***
* 接收Map
* @return
*/
@RequestMapping(value = "/add")
public String addUser(@RequestParam Map userMap){
System.out.println(userMap);
return "success";
}
}
3.2 List
修改addUser,加上一个注解@RequestParam来接收List数据
@Controller
@RequestMapping(value = "/user")
public class UserController {
/***
* 接收List
* 注意:接收List,需要在方法中加入注解@RequestParam
* 一会儿页面传过来的表单参数名字也要和方法名字id一致
* 例如:
* ID1:<input name="id">
* ID2:<input name="id">
* ID3:<input name="id">
* @return
*/
@RequestMapping(value = "/add")
public String addUser(@RequestParam List<Integer> id){
System.out.println(id);
return "success";
}
}
修改index.jsp表单
<form action="/user/add">
<div>
ID1:<input name="id" >
</div>
<div>
ID2:<input name="id" >
</div>
<div>
ID3:<input name="id" >
</div>
<div>
<input type="submit" value="提交">
</div>
</form>
4.实体引用类型(JavaBean)
JavaBean
创建IdCard
public class IdCard {
//身份证号
private String number;
//身份证地址
private String address;
//get..set..
}
修改User
public class User {
private String name;
private Integer age;
//引用IdCard作为子属性
private IdCard idCard;
//get.. set..
}
修改addUser
@Controller
@RequestMapping(value = "/user")
public class UserController {
/***
* 接收引用JavaBean
* 注意:页面填充表单的时候,name的值仍然要和后台接收的JavaBean的属性名一样。
* 但如果有引用属性填充,就写[引用属性名].[引用属性自身对应属性名]
* 例如:
* 身份证号:<input name="idCard.number" >
* 地址:<input name="idCard.address" >
*
* @return
*/
@RequestMapping(value = "/add")
public String addUser(User user){
System.out.println("用户" + user.getName() + "今年" + user.getAge() + "岁,住在" + user.getIdCard().getAddress() + ",身份证号是" + user.getIdCard().getNumber());
return "success";
}
}
修改index.jsp
<form action="/user/add">
<div>
名字:<input name="name" >
</div>
<div>
年龄:<input name="age" >
</div>
<div>
身份证号:<input name="idCard.number" >
</div>
<div>
地址:<input name="idCard.address" >
</div>
<div>
<input type="submit" value="提交">
</div>
</form>
5.JavaBean集合引用类型
如果JavaBean有集合属性,JSP页面编写方式:list[0].属性
创建Mobile
public class Mobile {
//手机名字
private String mobileName;
//手机价格
private Float price;
//get..set..
}
修改User
public class User {
private String name;
private Integer age;
//引用IdCard作为子属性
private IdCard idCard;
//一个人买了多个手机
private List<Mobile> mobiles;
//get.. set..
}
addUser方法不变,我们可以打印一些信息
@Controller
@RequestMapping(value = "/user")
public class UserController {
/***
* 接收引用JavaBean
* 注意:页面填充表单的时候,name的值仍然要和后台接收的JavaBean的属性名一样。
* 但如果有引用属性填充,就写[引用属性名].[引用属性自身对应属性名]
* 例如:
* 身份证号:<input name="idCard.number" >
* 地址:<input name="idCard.address" >
*
* 接收的JavaBean里如果存在List集合,则页面需要每次用下标来告诉程序是第几个,其他的用法和单个JavaBean用法一样
* 例如:
* 第1个手机名字:<input name="mobiles[0].mobileName" >
* 第1个手机价格:<input name="mobiles[0].price" >
*
* 第2个手机名字:<input name="mobiles[1].mobileName" >
* 第2个手机价格:<input name="mobiles[1].price" >
* @return
*/
@RequestMapping(value = "/add")
public String addUser(User user){
System.out.println("用户" + user.getName() + "今年" + user.getAge() + "岁,住在" + user.getIdCard().getAddress() + ",身份证号是" + user.getIdCard().getNumber());
for (Mobile mobile : user.getMobiles()) {
System.out.println(mobile.getMobileName()+"花了"+mobile.getPrice());
}
return "success";
}
}
修改index.jsp表单
<form action="/user/add">
<div>
名字:<input name="name" >
</div>
<div>
年龄:<input name="age" >
</div>
<div>
身份证号:<input name="idCard.number" >
</div>
<div>
地址:<input name="idCard.address" >
</div>
<div>
第1个手机名字:<input name="mobiles[0].mobileName" >
</div>
<div>
第1个手机价格:<input name="mobiles[0].price" >
</div>
<div>
第2个手机名字:<input name="mobiles[1].mobileName" >
</div>
<div>
第2个手机价格:<input name="mobiles[1].price" >
</div>
<div>
<input type="submit" value="提交">
</div>
</form>
6.解决post请求中文乱码问题
在web.xml中配置Spring提供的过滤器类
<!-- 配置过滤器,解决中文乱码的问题 -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!-- 指定字符集 -->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
7.自定义类型转换器
表单提交的任何数据类型全部都是字符串类型,Spring框架内部会默认进行数据类型转换。但Date类型并不能实现转换,需要我们手动解决。
自定义数据类型转换,可以实现Converter的接口
public class DateConverter implements Converter<String,Date>{
/***
* 将String类型转成Date类型
*/
public Date convert(String str) {
try {
//定义一个时间转换工具对象
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
//将字符串转Date并返回
return simpleDateFormat.parse(str);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
SpringMVC中增加配置
注册自定义类型转换器,在springmvc.xml配置文件中编写配置
<!-- 配置spring开启注解mvc的支持-->
<mvc:annotation-driven conversion-service="conversionService" />
<!--
注册自定义类型转换器
-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<bean class="com.itheima.util.DateConverter" />
</property>
</bean>
二.常用注解
1.RequestParam
作用:把请求中的指定名称的参数传递给控制器中的形参赋值
属性
value:请求参数中的名称
required:请求参数中是否必须提供此参数,默认值是true,必须提供
@RequestMapping(path="/hello")
public String sayHello(@RequestParam(value="username",required=false)String name) {
System.out.println(name);
return "success";
}
2.RequestBody
作用:用于获取请求体的内容(注意:get方法不可以)
属性
required:是否必须有请求体,默认值是true
@RequestMapping(path="/hello")
public String sayHello(@RequestBody String body) {
System.out.println(body);
return "success";
}
3.PathVariable
作用:拥有绑定url中的占位符的。例如:url中有/delete/{id},{id}就是占位符
属性
value:指定url中的占位符名称
代码如下:
<a href="user/hello/1">入门案例</a>
@RequestMapping(path="/hello/{id}")
public String sayHello(@PathVariable(value="id") String id) {
System.out.println(id);
return "success";
}
4.RequestHeader
作用:获取指定请求头的值
属性
value:请求头的名称
代码如下
@RequestMapping(path="/hello")
public String sayHello(@RequestHeader(value="Accept") String header) {
System.out.println(header);
return "success";
}
5.CookieValue
作用:用于获取指定cookie的名称的值
属性
value:cookie的名称
代码
@RequestMapping(path="/hello")
public String sayHello(@CookieValue(value="JSESSIONID") String cookieValue) {
System.out.println(cookieValue);
return "success";
}
6.ModelAttribute
6.1.作用
- 出现在方法上:表示当前方法会在控制器方法执行前线执行。
- 出现在参数上:获取指定的数据给参数赋值。
6.2.应用场景
- 当提交表单数据不是完整的实体数据时,保证没有提交的字段使用数据库原来的数据。
6.3.修饰的方法有返回值
在上面的案例基础之上,给User中添加一个sex属性,再到UserController中添加一个parameterUser()方法,并创建User再赋值返回,方法上加上注解@ModelAttribute注解。
@Controller
@RequestMapping(value = "/user")
public class UserController {
/***
* 优先执行
* @return
*/
@ModelAttribute
public User parameterUser(){
User user = new User();
user.setSex("男");
return user;
}
/***
* 此时的user已经被上面的parameterUser先执行了修改,已经给sex赋值
*/
@RequestMapping(value = "/add")
public String addUser(User user){
System.out.println("用户" + user.getName() +",性别:"+user.getSex()+","+ "今年" + user.getAge() + "岁,住在" + user.getIdCard().getAddress() + ",身份证号是" + user.getIdCard().getNumber());
for (Mobile mobile : user.getMobiles()) {
System.out.println(mobile.getMobileName()+"花了"+mobile.getPrice());
}
return "success";
}
}
6.4.修饰的方法没有返回值
在上面案例基础上,把parameterUser的返回值去掉,增加一个Map来存储数据,存储的key为user,在addUser中使用@ModelAttribute(“user”)User user获取在parameterUser()方法中赋值的数据。程序运行后,我们发现addUser方法的user参数能取到parameterUser方法赋值的数据。
@Controller
@RequestMapping(value = "/user")
public class UserController {
/***
* 优先执行
* @return
*/
@ModelAttribute
public void parameterUser(Map<String,User> userMap){
User user = new User();
user.setSex("男");
userMap.put("user",user);
}
/***
* 此时的user已经被上面的parameterUser先执行了修改,已经给sex赋值
*/
@RequestMapping(value = "/add")
public String addUser(@ModelAttribute("user")User user){
System.out.println("用户" + user.getName() +",性别:"+user.getSex()+","+ "今年" + user.getAge() + "岁,住在" + user.getIdCard().getAddress() + ",身份证号是" + user.getIdCard().getNumber());
for (Mobile mobile : user.getMobiles()) {
System.out.println(mobile.getMobileName()+"花了"+mobile.getPrice());
}
return "success";
}
}
7.Model
SpringMVC会把Model(模型信息)中的的数据放入到request域对象中,页面可以通过EL表达式来取request域中的数据。我们可以先写一个案例,在后台使用Model的addAttribute方法,页面使用EL表达式取数据。
创建 ModelController
@Controller
@RequestMapping(value = "/model")
public class ModelController {
/***
* Model的使用
* @param model
* @return
*/
@RequestMapping(value = "/add")
public String add(Model model){
model.addAttribute("msg","张三");
return "success";
}
}
success.jsp页面从request域中取数据
${msg}
${requestScope}
8.SessionAttributes
作用:用于多次执行控制器方法间的参数共享
属性
value:指定存入属性的名称
代码如下
@Controller
@RequestMapping(path="/user")
@SessionAttributes(value= {"username","password","age"},types= {String.class,Integer.class}) // 把数据存入到session域对象中
public class HelloController {
/**
* 向session中存入值
* @return
*/
@RequestMapping(path="/save")
public String save(Model model) {
System.out.println("向session域中保存数据");
model.addAttribute("username", "root");
model.addAttribute("password", "123");
model.addAttribute("age", 20);
return "success";
}
/**
* 从session中获取值
* @return
*/
@RequestMapping(path="/find")
public String find(ModelMap modelMap) {
String username = (String) modelMap.get("username");
String password = (String) modelMap.get("password");
Integer age = (Integer) modelMap.get("age");
System.out.println(username + " : "+password +" : "+age);
return "success";
}
/**
* 清除值
* @return
*/
@RequestMapping(path="/delete")
public String delete(SessionStatus status) {
status.setComplete();
return "success";
}
}