1.当我们提交表单,将表单中的数据绑定的方法的入参的对象中时,会涉及到数据绑定的流程,数据绑定的流程分为:数据类型转换、数据格式化、数据校验
- 数据类型转换
- SpringMVC默认为我们装配了以下类型转换器:
- 如果SpringMVC默认的类型转换器不能满足我们的需求,我们可以自定义类型转换器,如:将一个字符串转换为Employee对象
- 创建一个类实现Converter<S,T>接口
public class MyConverter
implements
//
Tom-tom@atguigu.com-1-101 这种格式的写法转换
@Override
public Employee convert(String arg0) {
employee = null;
if( arg0 !=
null){
split = arg0.split(
"-");
if( split !=
null &&
split.
length
//获取姓名
lastName = split[0];
//获取邮箱
email = split[1];
//获取性别
int gender = Integer.parseInt(
split[2]);
//获取部门的id
int deptId = Integer.parseInt(
split[3]);
//创建Employee对象
employee = new
employee.setLastName( lastName);
employee.setEmail( email);
employee.setGender( gender);
employee.setDepartment( new DepartmentDao().getDepartment(
deptId));
}
}
return employee;
}
}
• 在SpringMVC配置文件中配置自定义的类型转换器
<!-- 配置类型转换器 -->
< bean
id=
"conversionService"
class=
"org.springframework.context.support.ConversionServiceFactoryBean"
>
< property
name=
"converters"
>
< set
>
< bean
class=
"com.atguigu.springmvc.converter.MyConverter"
></
bean
>
</ set
>
</ property
>
</ bean
>
< mvc:annotation-driven
conversion-service=
"conversionService"
></
mvc:annotation-driven
>
这个必须写在 <
mvc:annotation-driven
></
mvc:annotation-driven
>之前才行
// 测试自定义转换器
@RequestMapping(value = "/testMyConverter", method = RequestMethod.
POST)
public String testMyConverter( @RequestParam(
"employee") Employee
employee) {
// 保存该员工
out.println( employee);
employeeDao.save( employee);
return "redirect:/getEmployees";
• 备注:
在Handler中通过 @InitBinder这个标签在数据绑定的过程不允许给某一个属性赋值
@InitBinder
public void initGender(WebDataBinder dataBinder){
//数据绑定的过程不允许给性别赋值
dataBinder.setDisallowedFields("gender");
}
• @InitBinder方法不能有返回值,它必须声明为void。
• @InitBinder方法的参数通常是 WebDataBinder
• 备注:
<mvc:annotation-driven/>配置在什么时候必须配置?
- 直接配置响应的页面:无需经过控制器来执行结果 ;但会导致其他请求路径失效,需要配置mvc:annotation-driven标签<mvc:view-controller path="/success" view-name="success"/>
- 通过jQuery执行delete请求时,找不到静态资源,需要配置mvc:annotation-driven标签
- 配置类型转换器服务时,需要指定转换器服务引用<mvc:annotation-driven conversion-service=“conversionService”/> 会将自定义的ConversionService 注册到 Spring MVC 的上下文中
- 数据验证,也需要配置
3.数据的格式化
- 我们可以通过@DateTimeFormat和@NumberFormat注解对应日期和数据进行格式化,只需要在要格式化的类的属性上添加以上注解即可
@DateTimeFormat(pattern =
"yyyy-MM-dd")
private Date birthday;
@NumberFormat(pattern= "#,###,###.##")
private double
salary;
• 要使@DateTimeFormat和@NumberFormat注解起作用,必须配置<mvc:annotation-driven></mvc:annotation-driven>
< mvc:annotation-driven
></
mvc:annotation-driven
>
配置,配置时不能指定conversion-service属性 ,否则,依然报错 400 。要把 <mvc:annotation-driven conversion-service="conversionService"/>注掉才行
备注:
FormattingConversionService 实现类, 既具有类型转换的功能,又具有格式化的功能
• <mvc:annotation-driven/> 默认创建的 ConversionService 实例即为
DefaultFormattingConversionService
4.数据校验
• 我们可以通过Hibernate Validator进行数据校验,使用它需要到导入以下jar包
classmate-0.8.0.jar
hibernate-validator-5.0.0.CR2.jar
hibernate-validator-annotation-processor-5.0.0.CR2.jar
jboss-logging-3.1.1.GA.jar
validation-api-1.1.0.CR1.jar
• 然后在要校验的属性上添加对应的注解
@NotEmpty
private String lastName;
@Email
private String email;
@Past
private Date birthday;
• 在要校验的属性对应的对象的前面添加@Valid注解,同时紧挨着该对象传入BindingResult类型的入参,通过它获取异常信息
// 添加新员工
@RequestMapping(value = "/emp", method = RequestMethod.
POST)
public String addEmployee( @Valid Employee
employee , BindingResult
result) {
// BindingResult结果集对象必须紧挨着被校验的employee对象,中间不能有其他参数
// System.out.println(employee);
int errorCount =
result.getErrorCount();
if( errorCount
//证明有错误信息
fieldErrors = result.getFieldErrors();
for (FieldError fieldError :
fieldErrors) {
//获取出现异常的属性
field = fieldError.getField();
//获取异常信息
message = fieldError.getDefaultMessage();
out.println( field+
":"+
message);
}
//转发到输入用户信息的页面
return "input";
}
// 保存用户
employeeDao.save( employee);
return "redirect:/emps";
}
• 要想当校验的注解起作用,必须配置<mvc:annotation-driven></mvc:annotation-driven>
< mvc:annotation-driven
></
mvc:annotation-driven
>
• 通过<form:errors></form:errors>表单在前端页面显示错误信息
<!-- SpringMVC提供的表单默认表单中的数据是必须要回显的,默认情况下,SpringMVC会以command 作为key从request域中
查询模型数据,然后回显,找不到则会抛出异常。我们可以通过form表单的modelAttribute属性来指定在request域中放的模型数据的key
-->
< form:form
modelAttribute=
"employee"
>
<!-- 如果path的值为通配符*,将显示所有的错误信息,如果要显示对应的错误信息,将该值设置为属性名即可-->
<%-- <form:errors path="*">
</form:errors>
--%>
<!-- path属性就相当于input中的name属性 -->
<!-- 当员工的id为null,即在添加新员工时再显示姓名 -->
< c:if
test=
"${
empty requestScope.employee.id }
"
>
< form:input
path=
"lastName"
/>
<
form:errors
path=
"lastName"
></
form:errors
>
<
br
>
</ c:if
>
<!-- 对应更新来说,需要将POST请求转换为PUT请求,所以需要传一个请求参数_method -->
< c:if
test=
"${!
empty requestScope.employee.id }
"
>
< form:hidden
path=
"id"
/>
< input
type=
"hidden"
name=
"_method"
value=
"put"
>
</ c:if
>
< form:input
path=
"email"
/>
<
form:errors
path=
"email"
></
form:errors
>
<
br
>
< form:radiobutton
path=
"gender"
value=
"1"
label=
"男"
/>
< form:radiobutton
path=
"gender"
value=
"0"
label=
"女"
/><
br
>
< form:select
path=
"department.id"
items=
"${requestScope.depts }
"
itemValue=
"id"
itemLabel=
"departmentName"
></
form:select
>
< br
>
< form:input
path=
"birthday"
/>
<
form:errors
path=
"birthday"
></
form:errors
>
<
br
>
< form:input
path=
"salary"
/><
br
>
< input
type=
"submit"
>
</ form:form
>
• 国际化错误信息
• 在SpringMVC的配置文件中配置国际化资源文件
<!-- 配置国际化资源文件 -->
< bean
id=
"messageSource"
class=
"org.springframework.context.support.ResourceBundleMessageSource"
>
< property
name=
"basename"
value=
"i18n"
></
property
>
</ bean
>
• 国际化资源文件(i18n_zh_CN.properties)
\u7528\u6237\u540D\u4E0D\u80FD\u4E3A\u7A7A
\u90AE\u7BB1\u683C\u5F0F\u4E0D\u6B63\u786E
\u4EB2\u7231\u7684\uFF0C\u4F60\u51FA\u751F\u7684\u65F6\u95F4\u8FD8\u6CA1\u5230\uFF0C\u5728\u4F60\u5988\u5988\u809A\u5B50\u91CC\u518D\u5446\u4E9B\u65F6\u65E5\u5427\uFF01\uFF01\uFF01