Converter(转换器)与Formatter(格式化)都可以用于将一种对象类型转换为另一种对象类型。Converter是通用元件,可以在应用程序的任意层中使用,而Fotermatter这是专门为Web层设计的。Validator(验证器)主要用于校验输入。

Converter(转换器)

创建Converter,必须编写实现org.springframework.core.convert.converter.Converter接口的一个Java类。该接口的实现声明如下:

public interface Converter<S,T>

这里的S标识源类型,T表示目标类型。这是一个将String转为Employee对象的转换器:

public class EmployeeConveter implements Converter<String,Employee> {}

为了使用springMVC应用程序中定制的Converter,需要在springMVC配置文件中编写一个名为conversionService的bean。bean的类名称必须为org.springframeword.context.support.ConversionServiceFactoryBean。这个bean必须包含一个converters属性,它将列出要在应用程序中使用的所有定制Converter。

<!-- 配置自定义类型转换器 -->
<bean id="employeeConveter" class="cn.lynu.converter.EmployeeConveter"></bean>
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<ref bean="employeeConveter"/>
</set>
</property>
</bean>

注意:不要忘了将这个employeeConveter 加入到IOC的控制中:<bean id="employeeConveter" class="cn.lynu.converter.EmployeeConveter"></bean>  亦或者使用@Component 注解配置该类加入到IOC容器中,这样就不需要在XML中配置了:

二者必须选择一种配置方法,将employeeConveter 加入到IOC容器中,因为我们在设置converters 的时候需要用到,不然就会报出找不到这个bean的异常:

随后,要是annotation-driver元素的conversion-service属性赋值bean名称,如下:

<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>

Formatter(格式化)

Formatter就像Converter一样,也是将一种类型转换为另一种类型。但是,Formatter的源类型必须是一个String,而Converter则适用用于任意源类型。Formatter更适合Web层,而Converter则可以用在任意层,为了转换SpringMVC应用程序表单中的用户输入,始终应该选择Formatter,而不是Converter。

为了创建Formatter,要编写一个实现org.springframework.format.Formatter接口的Java类。下面是这个接口的声明:

public interface Formatter<T>

这里的T表示输入字符串要转换的目标类型。

public class LocalDateFormatter implements Formatter<LocalDate> {}

该接口有parse和print两个方法。所有实现都必须覆盖它们。

T parse(String text,java.util.Locale locale)

String print(T object,java.util.Local local)

parse方法利用值当的Locale将一个String解析为String解析成目标类型。print方法与之相反,他返回目标对象的字符串表示法。

为了在springMVC中使用Formatter,需要利用名为conversionService的bean对它进行注册。bean的类名称必须为org.springframework.format.support.FormatterConversionServiceFactoryBean,这个bean可以用一个·formatters属性注册formatter,用一个converters属性注册converter。

    <bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="formatters">
<set>
<!--注册formatters-->
</set>
</property>
</bean>

注意:formatters/converters都是set类型,我们还需要给这个Formatter添加一个component-scan元素:

<context:component-scan base-package="cn.lynu.formatter" />

或者是使用@Component注解

随后,还要是annotation-driver元素的conversion-service属性赋值bean名称,如下:

<mvc:annotation-driven conversion-service="conversionService" />

Validator (验证器)

在springMVC中,有两种方式可以验证输入,即利用Spring自带的验证框架,或者利用JSR303实现。可以这样理解:Converter和Formatter作用于字段级。在MVC应用程序中,它们将一种类型转换为另一种;类型。而验证器则作用对象级,它决定某一对象的所有字段是否均有效,以及是否遵循某些规则。

一个典型的springMVC应用会同时用到formatters/converters和validators。

如果一个应用程序即使用了Formatter,又有validator(验证器),那么,应用中的事件顺序是这样的:在调用Controller期间,将会有一个或者多个Formatter,试图将输入字符串转换为domain对象中的field值。一但格式化成功,验证器就会开始介入。

Spring验证器

从一开始,Spring就设计了输入验证,甚至早于JSR303(Java验证规范),因此,因此可能一些老的springMVC项目还在使用,对于新的项目,还是建议使用JSR303

为了创建Spring验证器,要实现org.springframework.validation.Validator接口,并重写supports和validate两个方法。

package org.springframework.validation;
public interface Validator{
boolean supports(Class<?> clazz);
void validate(Object target,Errors error);
}

如果验证器可以指定的Class,supports方法将返回true。validate方法会验证目标对象,并将错误消息填入Errors对象。

Errors对象是org.springframework.validation.Errors接口的一个实例。Errors对象中包含一系列FieldError和ObjectError对象。FieldError表示被验证对象中的某个属性相关的错误。

编写验证器时,不需要直接创建Error对象,因为实例化ObjectError或FieldError花费了大量编程精力。这是因为ObjectError类的构造器需要4个参数,FieldError类构造器则需要7个参数。

Errors对象中的错误消息,可以利用springMVC表单标签库的Errors标签显示在HTML页面中。错误消息可以通过Spring支持国际化特征本地化(springMVC表单标签,国际化本地化随后再说)。

org.springframework.validation.ValidationUtis类是一个工具,有助于编写Spring验证器,我们直接使用它里面提供的验证方法完成Validator类的验证过程。

配置文件

验证器不需要显示注册,但是想要从某个属性文件中获得错误消息,则需要通过声明messagesSource bean,告诉spring要去哪里寻找这个文件:

<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>classpath:messages</value>
</list>
</property>
<property name="defaultEncoding" value="UTF-8"/>
<property name="cacheSeconds" value="120"/>
</bean>

建议都配上defaultEncoding,并将其设置为UTF-8,这样读取properties文件内容到页面显示就不会有乱码出现了。而且如果使用Maven构建项目时,properties文件如果放在src/main/resources下,都建议在写着文件路径的时候都加上classpath。

所有的验证出错信息都将放在BindingResult对象中,我们可以调用其方法判断验证时候出错:

if(bindingResult.hasErrors()){
//有错误出现
System.out.println("错误个数:"+bindingResult.getErrorCount());
System.out.println("错误为:");
for(FieldError error:bindingResult.getFieldErrors()) {
System.out.println(error.getField()+"\t"+error.getDefaultMessage());
}
}

其实这个BindingResult对象使用是有要求的,我们在下面介绍过JSR303之后再说

JSR303验证

JSR303通过租借给对象属性添加约束,但是JSR303只是一个规范,所以我们需要使用它的实现产品,目前两个实现:第一个时Hibernate Validator,第二个实现时Apache BVal。JSR303方便之处就在于不需要编写验证器,但要利用JSR303注解类型潜入约束。这些注解大都是javax.validation包下的类.

部分JSR303验证注解:

注解 描述 范例
@AssertTrue 应用于boolean属性,该属性必须为True

@AssertTrue

boolean isEmpty;

@DecimalMax 该属性的值必须为小于或等于指定值的小数

@DecimalMax("1.1")

BigDecimal price;

@Max 该属性值必须为一个小于或等于指定值的整数

@Max(150)

int age;

@Future 该属性必须为未来的一个日期  

@Future

Date shippingDate;

@Past 该属性值必须是过去的一个日期

@Past

Date birthDay;

@Size 该属性值必须在指定范围类

@Size(min=2,max=140)

String areaCode;

@NotNull

该属性值不能是null(建议使用Hibernate Validation的@NotEmpty,

因为页面字段为空会被封装为[] 而非null)

@NotNull

String firstName;

@Patter

该属性可以与指定的表达式相匹配(其实就是与正则匹配)

@Pattern(regext="\\d{3}")

String areaCode;

我们还是需要在springMVC中配置ReloadableResourceBundleMessageSource:

<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>classpath:messages</value>
</list>
</property>
<property name="defaultEncoding" value="UTF-8"/>
<property name="cacheSeconds" value="120"/>
</bean>

像使用Spring验证器一样,可以在messages.properties属性文件以下面格式来使用property键值,覆盖来自JSR303验证器的错误消息:

constraint.object.property

但是在5.2.4版本Hibernate Validation仍然无法验证使用@Part和@Future注解的LocalDate或LocalDateTime类型的字段,因为LocalDate/LocalDateTime是Java8新增的类型,是想用来替代java.util.Date。因此对于这种新的类型的验证需要使用第一种自定义spring验证器方式,或者是重写Hibernate Validation中的ConstraintHelper类。

JSR303验证的后台Java代码

注意:我们上面说到所有验证错误信息都会存在BindingResult这个对象中,但是这个对象使用是有要求的:它必须在放在验证对象(验证对象需要使用@Valid注解修饰 javax.validation.Valid)的后面,必须在后面,也就是说它们之间不能存在其他任何的参数:

    /**
* BindingResult将显示错误信息
*/
@RequestMapping(value="/emp",method=RequestMethod.POST)
public String save(@Valid Employee employee,BindingResult result,Model model) {
if(result.getErrorCount()>0) {
System.out.println("错误个数:"+result.getErrorCount());
System.out.println("错误为:");
for(FieldError error:result.getFieldErrors()) {
System.out.println(error.getField()+"\t"+error.getDefaultMessage());
}
//输出错误信息
List<ObjectError> allErrors = result.getAllErrors();
List<String> errorList=new ArrayList<String>();
for (ObjectError objectError : allErrors) {
try {
errorList.add(objectError.getDefaultMessage());
} catch (Exception e) {
e.printStackTrace();
}
}
//将错误信息传递到页面
model.addAttribute("allErrors", errorList);
model.addAttribute("departments", departmentDao.getDepartments());
return "input";
}
employeeDao.save(employee);
return "redirect:/list";
}

Converter(转换器)与Formatter(格式化) ,Validator(验证器)的更多相关文章

  1. springMVC的 Converter转换器 和 Formatter

    Converter转换器 spring的Converter是可以将一种类型转换成另一种类型的一个对象, 自定义Converter需要实现Converter接口 日期转换器 import java.te ...

  2. spring-Formatter(格式化器)-validator(验证器)-错误信息定制

    项目结构

  3. How to create XML validator(验证器;验证程序) from XML schema

    In order to check XML data for validity we have to prepare its schema XSD-file. This file will be lo ...

  4. springMVC中使用 JSR-303验证器( Validation 接口 )

    在pom.xml,添加validator验证器的依赖 <dependency> <groupId>org.hibernate</groupId> <artif ...

  5. [Swift]LeetCode591. 标签验证器 | Tag Validator

    Given a string representing a code snippet, you need to implement a tag validator to parse the code ...

  6. vue props 下有验证器 validator 验证数据返回true false后,false给default值

    vue props 下有验证器 validator 验证数据返回true false后,false给default值 props: { type: { validator (value) { retu ...

  7. PHP验证器类Validator

    Particle\Validator是一个小巧优雅的实用的PHP验证类库,提供了一个非常简洁的API.它无需依赖其他组件,提供友好的文档,并且有利于扩展. 安装 composer require pa ...

  8. Spring MVC -- 验证器

    输入验证是Spring处理的最重要Web开发任务之一.在Spring MVC中,有两种方式可以验证输入,即利用Spring自带的验证框架,或者利用JSR 303实现.本篇博客将介绍这两种输入验证方法. ...

  9. (翻译)Angular 1.3中的验证器管道

    原文地址:VALIDATORS PIPELINE IN ANGULAR 1.3 我们知道在Angular中操作表单是很爽的.因为Angular本身的作用域模型,我们总能在相应的作用域中获取到表单当前的 ...

随机推荐

  1. [置顶] 【机器学习PAI实践九】如何通过机器学习实现云端实时心脏状况监测

    背景 我们通过之前的案例已经为大家介绍了如何通过常规的体检数据预测心脏病的发生,请见http://blog.csdn.net/buptgshengod/article/details/53609878 ...

  2. async eachSeries如何按序列执行下去

    async callback要执行完才会进到一下个序列 async.mapSeries(files, function(file, outerCB) { var all = fs.readdirsyn ...

  3. [Python] 比较两个数组的元素的异同

    通过set()获取两个数组的交/并/差集: print set(a) & set(b) # 交集, 等价于set(a).intersection(set(b)) print set(a) | ...

  4. SSH服务及其扩展(sshpass和expect)

    SSH服务及其扩展(sshpass和expect) Linux SSH服务一共包含三个工具:ssh.scp.sftp [远程连接及执行命令] 语法:ssh -p端口 账号@IP 命令 参数说明:-o ...

  5. VUE 入门 01

    什么是VUE? 它是构建用户界面的JavaScript框架(让他自动生成js.css.html) 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用.Vu ...

  6. Android虚拟、实体键盘不能同时使用?

    /****************************************************************************** * Android虚拟.实体键盘不能同时 ...

  7. Linux系统管理员必备参考资料下载汇总

    Linux系统管理员必备: Linux系统管理工具包系列汇总 Linux系统管理员必看 VanDyke SecureCRT 6.1.3 附特别文件 鸟哥的Linux私房菜 基础学习篇 (第二版) 高清 ...

  8. SPOJ Favorite Dice(数学期望)

    BuggyD loves to carry his favorite die around. Perhaps you wonder why it's his favorite? Well, his d ...

  9. Filter学习(一)

    一.Filter简介 Filter:可以对web服务器管理的所有web资源(如Jsp, Servlet, 静态图片文件或静态 html 文件等)进行拦截,从而实现一些特殊的功能.例如实现URL级别的权 ...

  10. CF1109A Sasha and a Bit of Relax

    CF1109A Sasha and a Bit of Relax 用 \(xorsum[l,r]\) 表示 \(a[l] \oplus a[l+1] \oplus a[l+2]... a[r-1] \ ...