SpringMVC
1. 请求参数的绑定
1.1 请求参数的绑定说明
1.1.1 绑定机制
- 表单中请求参数都是基于
key=value
的。 SpringMVC
绑定请求参数的过程是通过把表单提交请求参数,作为控制器中方法参数进行绑定的。- 要求:提交表单的
name
和参数的名称是相同的
1.1.2 支持的数据类型
- 基本数据类型和字符串类型
- 实体类型(
JavaBean
) - 集合数据类型(
List
、Map
集合等)
1.1.3 使用要求
(1) 如果是基本类型或者 String 类型: 要求参数名称必须和控制器中方法的形参名称保持一致。 (严格区分大小写)
(2) 如果是 POJO 类型,或者它的关联对象: 要求表单中参数名称和 POJO
类的属性名称保持一致。并且控制器方法的参数类型是 POJO
类型。
(3)如果是集合类型,有两种方式:
- 第一种:
- 要求集合类型的请求参数必须在
POJO
中。在表单中请求参数名称要和POJO
中集合属性名称相同。 - 给
List
集合中的元素赋值, 使用下标。 - 给
Map
集合中的元素赋值, 使用键值对。
- 要求集合类型的请求参数必须在
- 第二种: 接收的请求参数是
json
格式数据。需要借助一个注解实现。
注意:
它还可以实现一些数据类型自动转换。 内置转换器全都在:
org.springframework.core.convert.support 包下。 有:
java.lang.Boolean -> java.lang.String : ObjectToStringConverter
java.lang.Character -> java.lang.Number : CharacterToNumberFactory
java.lang.Character -> java.lang.String : ObjectToStringConverter
java.lang.Enum -> java.lang.String : EnumToStringConverter
java.lang.Number -> java.lang.Character : NumberToCharacterConverter
java.lang.Number -> java.lang.Number : NumberToNumberConverterFactory
java.lang.Number -> java.lang.String : ObjectToStringConverter
java.lang.String -> java.lang.Boolean : StringToBooleanConverter
java.lang.String -> java.lang.Character : StringToCharacterConverter
java.lang.String -> java.lang.Enum : StringToEnumConverterFactory
java.lang.String -> java.lang.Number : StringToNumberConverterFactory
java.lang.String -> java.util.Locale : StringToLocaleConverter
java.lang.String -> java.util.Properties : StringToPropertiesConverter
java.lang.String -> java.util.UUID : StringToUUIDConverter
java.util.Locale -> java.lang.String : ObjectToStringConverter
java.util.Properties -> java.lang.String : PropertiesToStringConverter
java.util.UUID -> java.lang.String : ObjectToStringConverter
......
如遇特殊类型转换要求,需要我们自己编写自定义类型转换器。
1.2 基本数据类型和字符串类型作为参数
- 提交表单的
name
和参数的名称是相同的 - 区分大小写
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%-- 请求参数绑定--%>
<a href="/param/testParam?username=tom&password=123">请求参数绑定</a>
</body>
</html>
/**
* 请求参数绑定入门
* @return
*/
@RequestMapping("/testParam")
public String testParam(String username, String password){
System.out.println("执行了...");
System.out.println("用户名:" + username);
System.out.println("密码:" + password);
return "success";
}
1.3 实体类型(JavaBean)
- 提交表单的
name
和JavaBean
中的属性名称需要一致 - 如果一个
JavaBean
类中包含其他的引用类型,那么表单的name
属性需要编写成:对象.属性
例如:address.name
package com.spg.domain;
import java.io.Serializable;
import java.util.Date;
public class User implements Serializable {
private String uname;
private Integer age;
private Date date;
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
@Override
public String toString() {
return "User{" +
"uname='" + uname + '\'' +
", age=" + age +
", date=" + date +
'}';
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%-- 把数据封装到Account中 --%>
<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" name="" value="提交"/><br/>
</form>
</body>
</html>
/**
* 请求参数绑定把数据封装到JavaBean的类中
* @return account
*/
@RequestMapping("/saveAccount")
public String saveAccount(Account account){
System.out.println("执行了...");
System.out.println(account);
return "success";
}
1.4 给集合属性数据封装
JSP页面编写方式:list[0].属性
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%-- 把数据封装到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" name="" value="提交"/><br/>
</form>
</body>
</html>
/**
* 请求参数绑定把数据封装到JavaBean的类中
* @return account
*/
@RequestMapping("/saveAccount")
public String saveAccount(Account account){
System.out.println("执行了...");
System.out.println(account);
return "success";
}
1.5 请求参数中文乱码的解决
在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>
1.6 自定义类型转换器
- 表单提交的任何数据类型全部都是字符串类型,但是后台定义
Integer
类型,数据也可以封装上,说明Spring
框架内部会默认进行数据类型转换。 - 如果想自定义数据类型转换,可以实现
Converter
的接口
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%-- 自定义类型转换器 --%>
<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" name="" value="提交"/><br/>
</form>
</body>
</html>
/**
* 自定义类型转换器
* @param user
* @return
*/
@RequestMapping("/saveUser")
public String saveUser(User user){
System.out.println("执行了...");
System.out.println(user);
return "success";
}
运行结果:
解决方案:
(1)自定义类型转换器:
package com.spg.utils;
import org.springframework.core.convert.converter.Converter;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 把字符串转化为日期
*/
public class StringToDateConverter implements Converter<String, Date>{
/**
* 进行类型转换的方法
* @param s 传入进来的字符串
* @return
*/
@Override
public Date convert(String s) {
// 判断
if(s == null){
throw new RuntimeException("请您传入数据:");
}
try {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
// 把字符串转换日期
return df.parse(s);
} catch (Exception e) {
throw new RuntimeException("数据类型转换出现错误!");
}
}
}
(2) 注册自定义类型转换器,在springmvc.xml
配置文件中编写配置:
<!-- 配置类型转换器工厂 -->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<!-- 给工厂注入一个新的类型转换器 -->
<property name="converters">
<set>
<!-- 配置自定义类型转换器 -->
<bean class="com.spg.utils.StringToDateConverter"/>
</set>
</property>
</bean>
<!-- 配置spring开启注解mvc的支持 -->
<!-- 引用自定义类型转换器 -->
<mvc:annotation-driven conversion-service="conversionService"/>
这样就解决了
1.7 在控制器中使用原生的ServletAPI对象
SpringMVC
还支持使用原始 ServletAPI
对象作为控制器方法的参数。支持原始 ServletAPI
对象有:HttpServletRequest
、HttpServletResponse
、HttpSession
、java.security.Principal
、Locale
、InputStream
、OutputStream
、Reader
、Writer
只需要在控制器的方法参数定义HttpServletRequest
和HttpServletResponse
对象
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%-- Servlet原生的API --%>
<a href="/param/testServlet">Servlet原生的API</a>
</body>
</html>
/**
* 原生的API
* @return
*/
@RequestMapping("/testServlet")
public String testServlet(HttpServletRequest request, HttpServletResponse response){
System.out.println("执行了...");
System.out.println(request);
HttpSession session = request.getSession();
System.out.println(session);
ServletContext servletContext = session.getServletContext();
System.out.println(servletContext);
return "success";
}