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. Kotlin Reference (三) Coding Conventions

    most from reference 命名规则 1.使用驼峰式命名规则,尽量避免在命名中使用下划线 2.类型以大写字母开头 3.方法和属性以小写字母开头 4.使用4个空格缩进 5.public的方法 ...

  2. SSH 首次登录太慢问题

    这两天在使用 Docker 做测试,发现新建的容器在首次 ssh 登录的时候经常超时,我们简单将超时时间设置成60秒,但仍然会偶尔超时.所以简单延迟超时时间此路不通. 于是想到是否可以通过修改 ssh ...

  3. 使用TR1的智能指针

    作为C++程序员,在没有智能指针,手动管理内存的蛮荒岁月里,可以说是暗无天日,痛苦异常.直到上帝说,还是要有光,于是智能指针进了标准.C++码农的日子总算好起来了. 虽然一直鄙视着没有显式指针的语言, ...

  4. I.MX6 linux eGalaxTouch 自动获取设备节点

    I.MX6 linux eGalaxTouch 自动获取设备节点 \\\\\\\\\\\\\\-*- 目录 -*-///////////// | 一. 需求: | 二. /proc/bus/input ...

  5. (转)如何转载CSDN的文章

    前言   对于喜欢逛CSDN的人来说,看别人的博客确实能够对自己有不小的提高,有时候看到特别好的博客想转载下载,但是不能一个字一个字的敲了,这时候我们就想快速转载别人的博客,把别人的博客移到自己的空间 ...

  6. 程序设计入门-C语言基础知识-翁恺-第五周:函数-详细笔记(五)

    目录 第五周:函数 5.1 函数 5-2 使用函数 5.3 课后习题 第五周:函数 5.1 函数 什么是函数? 函数是一块代码,接受零个或多个参数,做一件事情,并返回零个或一个值. 函数声明语法 返回 ...

  7. 网站部署,网站要求需要支持mb_substring

    如果没有这个函数,php可能会出现中文乱码,处理方法如下: # yum install php-mbstring   //安装 之后在/etc/php.ini中添加extension=mbstring ...

  8. canvas设置长宽

    Canvas元素默认宽 300px, 高 150px, 设置其宽高可以使用如下方法:方法一:1 <canvas width="500" height="500&qu ...

  9. DVD项目

    package sy.com.cn;import java.util.*; public class DvdWorker { public static void main(String[]args) ...

  10. NET Core2基于RabbitMQ对Web前端实现推送功能

    NET Core2基于RabbitMQ对Web前端实现推送功能 https://www.cnblogs.com/Andre/p/10012329.html 在我们很多的Web应用中会遇到需要从后端将指 ...