根据B站视频整理:https://www.bilibili.com/video/BV1Mt411G7A8?p=1
2、请求参数的绑定
2.1、请求参数的绑定。获取单一请求参数
如下java代码,如果在方法括号里加了参数,在url地址栏中(http://localhost:8080/param/testParam?username=1111)有username=xxx,就可以获取这个值。
@RequestMapping("/testParam")
public String testParam(String username){
System.out.println("执行了,print:"+username);
return "success";
}
2.2、封装类。获取一个类
把数据封装到Account类中。
(1)实体类Account
public class Account implements Serializable {
private String username;
private String password;
private Double money;
//get,set方法和toString方法省略
}
(2)param.jsp中表单
form表单中的name值要和实体类中的属性名对应,否则获取不到。姓名不能输中文,乱码。
<form action="param/saveAccount" method="post">
姓名:<input type="text" name="username" /> <br>
密码:<input type="text" name="password" /> <br>
金额:<input type="text" name="money" /> <br>
<input type="submit" value="提交">
</form>
(3)controller类中
//请求参数绑定把数据封装到JavaBean的类中。就是类
@RequestMapping("/saveAccount")
public String saveAccount(Account account){
System.out.println(account);
return "success";
}
2.3、类里面有类的引用
把数据封装到Account类中,Account类中有User类。
(1)Account类
public class Account implements Serializable {
private String username;
private String password;
private Double money;
private User user;
//生成get、set和toString方法
}
(2)User类
public class User implements Serializable {
private String uname;
private Integer age;
//生成get、set和toString方法
}
(3)param.jsp中name值应加上类名
<form action="param/saveAccount" method="post">
姓名:<input type="text" name="username" /> <br>
密码:<input type="text" name="password" /> <br>
金额:<input type="text" name="money" /> <br>
用户姓名:<input type="text" name="user.uname" /> <br>
用户年龄:<input type="text" name="user.age" /> <br>
<input type="submit" value="提交">
</form>
2.4、解决中文乱码
在web.xml中添加过滤器
<!--解决中文乱码的过滤器-->
<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>
2.5、请求参数绑定集合
把数据封装到Account类中,Account类中有list和map集合。
(1)Account类
public class Account implements Serializable {
private String username;
private String password;
private Double money;
private List<User> list;
private Map<String,User> map;
//生成get、set和toString方法
}
(2)param.jsp
<%--把数据封装到Account类中,Account类中有list和map集合。--%>
<form action="param/saveAccount" method="post">
姓名:<input type="text" name="username" /> <br>
密码:<input type="text" name="password" /> <br>
金额:<input type="text" name="money" /> <br>
用户姓名:<input type="text" name="list[0].uname" /> <br>
用户年龄:<input type="text" name="list[0].age" /> <br>
用户姓名:<input type="text" name="map['one'].uname" /> <br>
用户年龄:<input type="text" name="map['one'].age" /> <br>
<input type="submit" value="提交">
</form>
2.6、自定义类型转换器
(1)定义类StringToDateConverter,实现Converter
package com.lu.utils;
import org.springframework.core.convert.converter.Converter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
public class StringToDateConverter implements Converter<String, Date> {
//传入进来字符串
public Date convert(String s) {
if (s == null){
throw new RuntimeException("请您传入数据");
}
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
try {
//把字符串转换日期
return df.parse(s);
}catch (Exception e){
throw new RuntimeException("数据类型转换出错");
}
}
}
(2)User类
public class User implements Serializable {
private String uname;
private Integer age;
private Date date;
//get,set和toString方法
}
(3)param.jsp
<form action="param/saveUser" method="post">
用户姓名:<input type="text" name="uname" /> <br>
用户年龄:<input type="text" name="age" /> <br>
用户生日:<input type="text" name="date" /> <br>
<input type="submit" value="提交">
</form>
(4)注册自定义类型转换器,在springmvc.xml配置文件中编写配置
<!--配置自定义类型转换器-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.lu.utils.StringToDateConverter"/>
</set>
</property>
</bean>
<!--开启SpringMVC框架注解的支持.conversion-service让自定义转换器生效-->
<mvc:annotation-driven conversion-service="conversionService"/>
3、常用注解
3.1、@RequestParam(接收普通参数的注解)
作用:把请求中的指定名称的参数给控制器中的形参赋值。
就是在名称不一样,获取不到值,但使用这个注解可以解决。
(1)在webapp下创建anno.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--常用的注解--%>
<a href="anno/testRequestParam?name=张三">RequestParam</a>
</body>
</html>
(2)创建AnnoController类
如下,这是未使用注解,定义的要和url中的一致,可以获取到值。
@Controller
@RequestMapping("/anno")
public class AnnoConotroller {
@RequestMapping("/testRequestParam")
public String testRequestParam(String name){
System.out.println("执行了:"+name);
return "success";
}
}
但是如果,定义了String uname;上边的代码就获取不到值。此时就需要RequestParam注解,在RequestParam注解定义了,必须要有这个参数名称,不然报错。
@Controller
@RequestMapping("/anno")
public class AnnoConotroller {
@RequestMapping("/testRequestParam")
public String testRequestParam(@RequestParam(name="name") String uname){
System.out.println("执行了:"+uname);
return "success";
}
}
3.2、@RequestBody(获取请求体中的数据)
作用:主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的)。直接使用得到的是key=value&key=value…结构的数据,get请求不适应,因为没有请求体。
属性:requeired:是否必须有请求体。默认值:true。当取值为true是,get请求方式会报错。如果取值为false,get请求得到的是null。
代码:
(1)anno.jsp中添加表单
<form action="anno/testRequestBody" method="post">
用户姓名:<input type="text" name="uname" /> <br>
用户年龄:<input type="text" name="age" /> <br>
<input type="submit" value="提交">
</form>
(2)AnnoConotroller类
//获取请求体内容
@RequestMapping("/testRequestBody")
public String testRequestBody(@RequestBody String body){
System.out.println("执行了:"+body);
return "success";
}
3.3、@PathVaribale(映射 URL 绑定的占位符)
作用:用于绑定url中的占位符。例如:请求url中/delete/{id},这个id就是占位符
spring3.0之后加入的。是支持rest风格URL的一个重要标志。
属性:
value:用于指定url占位符的名称
required:是非必须提供占位符。
REST风格URL,一般称作restful风格,核心价值在于如何设计出符合REST风格的网络接口。
根据请求方式不同,来执行类中不同的方法。如果请求方式相同,可以加一个占位符来区分。
代码:
(1)anno.jsp中添加
<a href="anno/testPathVaribale/10">testPathVaribale</a> <br>
(2)AnnoConotroller类
@RequestMapping("/testPathVaribale/{id}")
public String testPathVaribale(@PathVariable(name="id") String id){
System.out.println("执行了:"+ id);
return "success";
}
可以获得id=10。
3.4、@RequestHeader(获取请求头中的数据)
作用:主要是将请求头的信息区数据,映射到功能处理方法的参数上。
实际开发中不怎么用。
代码:
(1)anno.jsp中添加
<a href="anno/testRequestHeader">testRequestHeader</a> <br>
(2)AnnoConotroller类
//获取请求体
@RequestMapping("/testRequestHeader")
public String testRequestHeader(@RequestHeader(value = "Accept") String header){
System.out.println("执行了:"+ header);
return "success";
}
3.5、@CookieValues(获取请求的Cookie数据)
作用:将请求的Cookie数据,映射到功能处理方法的参数上。
用的比较少。
代码:
anno.jsp中添加
<a href="anno/testCookieValue">testCookieValue</a> <br>
AnnoConotroller类
//获取cookie的值
@RequestMapping("/testCookieValue")
public String testCookieValue(@CookieValue(value = "JSESSIONID") String cookieValue){
System.out.println("执行了:"+ cookieValue);
return "success";
}
3.6、@ModelAttribute
作用:SpringMVC4.3版本以后加入的。可以用于修饰方法和参数。
出现在方法上,表示当前方法会在控制器的方法执行之前,先执行。可以有返回值,也可以没有返回值。
出现在参数上,获取指定的数据给参数赋值。
属性:value,用于获取数据key。key可以是pojo的属性名称,也可以是map结构的key。
应用场景:当表单提交数据不是完整的实体类数据时,保证没有提交数据的字段使用数据库对象。
例如,我们在编辑一个用户时,用户有一个创建信息字段,该字段的值是不允许被修改的。在提交表单数据是肯定没有此字段内容,一旦更新会把字段设置为null,此时就可以使用此注解解决这个问题。
代码:
(1)anno.jsp中添加
<form action="anno/testModelAttribute" method="post">
用户姓名:<input type="text" name="uname" /> <br>
用户年龄:<input type="text" name="age" /> <br>
<input type="submit" value="提交">
</form> <br>
(2)AnnoConotroller类,有返回值写法
@RequestMapping("/testModelAttribute")
public String testModelAttribute(User user){
System.out.println("执行了testModelAttribute" );
System.out.println(user);
return "success";
}
//该方法会先执行,有返回值写法
@ModelAttribute
public User showUser(String uname){
System.out.println("showUser先执行了");
//通过用户名查询数据库(模拟)
User user = new User();
user.setUname(uname);
user.setAge(20);
user.setDate(new Date());
return user;
}
AnnoConotroller类,无返回值写法,存到map集合中,然后使用注解获取。
//没有返回值时,要用注解获取一下
@RequestMapping("/testModelAttribute")
public String testModelAttribute(@ModelAttribute("userMessage") User user){
System.out.println("执行了testModelAttribute" );
System.out.println(user);
return "success";
}
//该方法会先执行,没有返回值写法
@ModelAttribute
public void showUser(String uname, Map<String,User> map){
System.out.println("showUser先执行了");
//通过用户名查询数据库(模拟)
User user = new User();
user.setUname(uname);
user.setAge(20);
user.setDate(new Date());
map.put("userMessage",user);
}
3.7、@SessionAttributes(用于在多个请求之间传递参数)
作用:用于多次执行控制器方法间的参数共享。
属性:value,用于指定出入的属性名称
type,用于指定出入的数据类型
代码:
(1)anno.jsp中添加
<a href="anno/testSessionAttributes">testSessionAttributes</a>
<a href="anno/getSessionAttributes">testSessionAttributes</a>
<a href="anno/delSessionAttributes">delSessionAttributes</a>
(2)success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>入门成功</h3>
<%--isELIgnored="false" 表示不忽略这个表达式--%>
<%--
获取整个
${requestScope} --%>
${msg}
${sessionScope}
</body>
</html>
(3)AnnoConotroller类
@RequestMapping("/testSessionAttributes")
public String testSessionAttributes(Model model){
System.out.println("执行了testSessionAttributes" );
//底层会存储到request域对象中
model.addAttribute("msg","美美");
return "success";
}
//从session域中把值取出来
@RequestMapping("/getSessionAttributes")
public String getSessionAttributes(ModelMap modelMap){
String msg = (String)modelMap.get("msg");
System.out.println(msg);
return "success";
}
//从session域中删除
@RequestMapping("/delSessionAttributes")
public String delSessionAttributes(SessionStatus status){
status.setComplete();//设置完成. 删除掉
return "success";
}