springmvc学习----8.数据转换&数据格式化&数据校验
程序员文章站
2024-03-24 17:19:52
...
数据转换&数据格式化&数据校验
从页面提交的数据都是字符串,和javabean进行绑定就涉及到以下问题:
- 数据绑定期间的数据类型转换
- 数据绑定期间的数据格式化问题
- 数据校验
WebDataBinder:数据绑定器负责数据绑定工作,数据绑定【BindingResult保存结果】期间的类型转换【ConversionService】、格式化【ConversionService】、数据校验【Validator】等问题。
流程:
自定义类型转换
spring支持的转换器:
- ConversionServiceFactoryBean中:
- Converter<S,T>:将S类型转为T类型对象
- ConverterFactory:将相同系列多个"同质"Converter封装在一起,如果希望将一种类型的对象转换为另一种类型及其子类的对象(例如将String转换为Number及Number子类)可使用转换器工厂类
- GenericConverter:会根据源类对象及目标类对象所在的宿主类中的上下文信息进行类型转换
步骤:
- 实现Converter接口
- Converter是ConversionService中的组件,把Converter放进ConversionService中,再把ConversionService放进WebDataBinder
页面增加一个快速添加的表单:
<form action="${APP_PATH }/quickadd">
<input type="text" name="empinfo" value="无名氏aaa@qq.com" />
<input type="submit" value="快速添加" />
</form>
自定义类型转换器:
public class MyConverter implements Converter<String, Employee>{
/**
* 自定义类型转换器
*/
@Override
public Employee convert(String empInfo) {
Employee employee = null;
if(empInfo.contains("-")) {
String msg[] = empInfo.split("-");
employee = new Employee();
employee.setName(msg[0]);
employee.setEmail(msg[1]);
employee.setGender(Integer.parseInt(msg[2]));
employee.setDepartment(new Department(Integer.parseInt(msg[3]),null));
}
return employee;
}
}
在springmvc.xml中进行配置:
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.yxy.crud.component.MyConverter"></bean>
</set>
</property>
</bean>
<mvc:annotation-driven />会自动注册RequestMappingHandlerMapping、RequestMappingHandlerAdapter与ExceptionHandlerExceptionResolver三个bean
此外,还提供以下支持:
- 支持使用ConversionService实例对表单参数进行类型转换
- 支持使用@NumberFormat annotation、@DateTimeFormat注解完成数据类型的格式化
- 支持使用@Valid注解对JavaBean实例进行JSR303验证
- 支持使用@RequestBody和@ResponseBody注解
tips:BeanDefinitionParser就是解析各种标签的,例如:annotation-driven,util:list/map等等
数据校验
对于springmvc来讲我们可以使用JSR303来实现数据校验:
JSR303的一个实现:Hibernate Validator
扩展注解:
注解 | 功能说明 |
---|---|
被注释的元素必须是电子邮箱地址 | |
@Length | 被注释的字符串的大小必须在指定的范围内 |
@NotEmpty | 被注释的字符串必须非空 |
@Range | 被注释的元素必须在合适的范围内 |
后端校验:
@Nullable
private Integer eid;
@NotEmpty
@Length(min = 6,max = 18)
private String name;
@Email
private String email;
@Past //必须是一个过去的时间,对应@Future,必须是未来的时间
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birth;
private Double salary;
@NotNull
private Integer gender;
@Nullable
private Department department;
--------------------------------------------------------------------------------------------------------------
@RequestMapping(value = "/emp",method = RequestMethod.POST)
public String addEmp(@Valid Employee employee,BindingResult bindingResult) {
if(bindingResult.hasErrors()) {
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
for (FieldError fieldError : fieldErrors) {
System.out.println("错误消息提示:"+fieldError.getDefaultMessage());
System.out.println("错误字段:"+fieldError.getField());
System.out.println(fieldError);
System.out.println("^_^___^_^___^_^___^_^");
}
return "add";
}else {
employeeDao.save(employee);
}
return "redirect:/emps";
}
页面显示错误信息:
用户名:
<p>
<form:input path="name"/>
<form:errors path="name" />
</p>
邮箱:
<p>
<form:input path="email"/>
<form:errors path="email" />
</p>
生日:
<p>
<form:input path="birth"/>
<form:errors path="birth" />
</p>
<p>
性别:
<form:radiobutton path="gender" value="0"/> 男
<form:radiobutton path="gender" value="1"/> 女
<form:errors path="gender" />
</p>
定制国际化错误消息:
codes:
- Email.employee.email //校验规则.隐含模型中这个对象的key.对象的属性
- Email.email //校验规则.属性名
- Email.java.lang.String //校验规则.属性类型
- Email //校验规则
配置文件:精确优先
Email.email=email incorrect!!
NotEmpty=must not empty!!
Length.java.lang.String=length must between {2} and {1}!!
Past=must a past time!!
NotNull=must not null!!
typeMismatch.birth=birth incorrect!!
配置springmvc管理国际化资源文件:
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="errors"></property>
</bean>
效果大概这个样子:
当然一般项目是没有国际化需求的,所以我们可以通过设置message来定制错误信息
示例:
@NotEmpty(message = "不能为空")
@Length(min = 6,max = 18,message = "长度必须在6到18之间")
private String name;
@Email(message = "邮箱格式不正确")
private String email;
@Past(message = "必须是一个过去的时间") //必须是一个过去的时间,对应@Future,必须是未来的时间
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birth;