• 数据类型转换简介
  • Spring Web MVC中的数据类型转换
  • 内建的类型转换器
  • 自定义类型转换器

1      数据类型转换简介

当从页面提交数据到后台Action的时候,通过请求发送的数据,通常都是字符串类型的,不能满足后台Model中的数据类型的需要,因此需要进行数据类型转换。

从Spring3开始,我们可以使用如下架构进行类型转换、验证及格式化:

基本的流程:

①     类型转换:内部的ConversionService会根据S源类型/T目标类型自动选择相应的Converter SPI进行类型转换,而且是强类型的,能在任意类型数据之间进行转换;

②     数据验证:支持JSR-303验证框架,如将@Valid放在需要验证的目标类型上即可;

②     格式化显示:其实就是任意目标类型---->String的转换,完全可以使用Converter SPI完成。

Spring为了更好的诠释格式化/解析功能提供了Formatter SPI,支持根据Locale信息进行格式化/解析,而且该套SPI可以支持字段/参数级别的细粒度格式化/解析。

Formatter SPI最大特点是能进行字段/参数级别的细粒度解析/格式化控制,即使是Converter SPI也是粗粒度的(到某个具体类型,而不是其中的某个字段单独控制),目前Formatter SPI还不是很完善。Formatter SPI内部实现实际委托给Converter SPI进行转换,即约束为解析/格式化String<---->任意目标类型。

2      Spring Web MVC中的数据类型转换

在Spring Web MVC环境中,数据类型转换、验证及格式化通常是这样使用的:

①类型转换:首先表单数据(全部是字符串)通过WebDataBinder进行绑定到命令对象,内部通过Converter SPI实现;

②数据验证:使用JSR-303验证框架进行验证;

③格式化显示:展示通过Converter SPI格式化的数据和错误信息。

3      内建的类型转换器

第一组:标量转换器

1:StringToBooleanConverter :String----->Boolean

如:true:true/on/yes/1; false:false/off/no/0

2:ObjectToStringConverter :Object----->String ,调用toString方法转换

3:StringToNumberConverterFactory :String----->Number(如Integer、Long等)

4:NumberToNumberConverterFactory :Number子类型(Integer、Long、Double等)<——> Number子类型(Integer、Long、Double等)

5:StringToCharacterConverter :String-->java.lang.Character,取字符串第一个字符

6:NumberToCharacterConverter :Number子类型(Integer、Long、Double等)——> java.lang.Character

7:CharacterToNumberFactory :java.lang.Character —>Number子类型(Integer、Long、Double等)

8:StringToEnumConverterFactory :String----->enum类型,通过Enum.valueOf将字符串转换为需要的enum类型

9:EnumToStringConverter :enum类型----->String,返回enum对象的name()值

10:StringToLocaleConverter :String----->java.util.Local

11:PropertiesToStringConverter :java.util.Properties----->String,默认通过ISO-8859-1解码

12:StringToPropertiesConverter :String----->java.util.Properties,默认使用ISO-8859-1编码

第二组:集合、数组相关转换器

1:ArrayToCollectionConverter :任意S数组---->任意T集合(List、Set)

2:CollectionToArrayConverter :任意T集合(List、Set)---->任意S数组

3:ArrayToArrayConverter :任意S数组<---->任意T数组

4:CollectionToCollectionConverter :任意T集合(List、Set)<---->任意T集合(List、Set),即集合之间的类型转换

5:MapToMapConverter :Map<---->Map之间的转换

6:ArrayToStringConverter :任意S数组---->String类型

7:StringToArrayConverter :String--->数组,默认“,”分割,且去除字符串的两边空格

8:ArrayToObjectConverter :任意S数组---->任意Object的转换,(如果目标类型和源类型兼容,直接返回源对象;否则返回S数组的第一个元素并进行类型转换)

9:ObjectToArrayConverter :Object----->单元素数组

10:CollectionToStringConverter :任意T集合(List、Set)--->String类型

11:StringToCollectionConverter :String----->集合(List、Set),默认通过“,”分割,且去除字符串的两边空格(trim)

12:CollectionToObjectConverter :任意T集合---->任意Object的转换,(如果目标类型和源类型兼容,直接返回源对象;否则返回S数组的第一个元素并进行类型转换)

13:ObjectToCollectionConverter :Object----->单元素集合

第三组:默认(fallback)转换器,之前的转换器不能转换时调用

1:ObjectToObjectConverter :

Object(S)----->Object(T),首先尝试valueOf进行转换、没有则尝试new 构造器(S)

2:IdToEntityConverter :

Id(S)----->Entity(T),查找并调用public static T    find[EntityName](S)获取目标对象,EntityName是T类型的简单类型

3:FallbackObjectToStringConverter :

Object----->String,ConversionService作为恢复使用,即其他转换器不能转换时调用(执行对象的toString()方法)

如上的转换器在使用转换服务实现DefaultConversionService和DefaultFormattingConversionService时会自动注册。

4      自定义类型转换器

通过一个示例来说明,实现自定义String--->PhoneNumberModel的转换器:

 

需求:将座机号码转换成区号和号码两个部分保存

1)         转换器

 package com.inspur.converter;

 import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.springframework.core.convert.converter.Converter;
import org.springframework.util.StringUtils;
import com.inspur.pojo.PhoneNumberModel; public class StringToPhoneNumberConverter implements Converter<String, PhoneNumberModel> {
Pattern pattern = Pattern.compile("^(\\d{3,4})-(\\d{7,8})$"); public PhoneNumberModel convert(String source) {
if (!StringUtils.hasLength(source)) {
// ①如果source为空返回null
return null;
}
Matcher matcher = pattern.matcher(source);
if (matcher.matches()) {
// ②如果匹配进行转换
PhoneNumberModel phoneNumber = new PhoneNumberModel();
phoneNumber.setAreaCode(matcher.group(1));
phoneNumber.setPhoneNumber(matcher.group(2));
return phoneNumber;
} else {
// ③如果不匹配转换失败
throw new IllegalArgumentException(String.format(
"类型转换失败,需要格式[010-12345678],但格式是[%s]", source));
}
}
}

2)         使用的model

 public class PhoneNumberModel {
private String areaCode;//区号
private String phoneNumber;//电话号码
//省略get/set……
}

3)         简单的测试代码

 package com.inspur.test;
import org.springframework.core.convert.support.DefaultConversionService;
import com.inspur.converter.StringToPhoneNumberConverter;
import com.inspur.pojo.PhoneNumberModel;
public class ConverterTest {
/**
* 需求:将座机号码转换成区号和号码两个部分保存
* @param args
*/
public static void main(String[] args) {
DefaultConversionService conversionService = new DefaultConversionService();
conversionService.addConverter(new StringToPhoneNumberConverter());
String phoneNumberStr = "010-12345678";
PhoneNumberModel phoneNumber = conversionService.convert(phoneNumberStr, PhoneNumberModel.class);
System.out.println("区号==" + phoneNumber.getAreaCode()+" 号码==" + phoneNumber.getPhoneNumber());
}
}

注册ConversionService实现和自定义的类型转换器

4)         集成到Spring Web MVC环境

 <!-- 注册ConversionService实现和自定义的类型转换器 -->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="com.inspur.converter.StringToPhoneNumberConverter" />
</list>
</property>
</bean>

converters:注册我们自定义的类型转换器,此处注册了String--->PhoneNumberModel。FormattingConversionServiceFactoryBean:是FactoryBean实现,默认使用DefaultFormattingConversionService转换器服务实现;

  • 在<mvc:annotation-drive>里面配置conversion-service属性

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

04springMVC数据类型转换的更多相关文章

  1. JavaScript中数据类型转换总结

    JavaScript中数据类型转换总结 在js中,数据类型转换分为显式数据类型转换和隐式数据类型转换. 1, 显式数据类型转换 a:转数字: 1)Number转换: 代码: var a = " ...

  2. Sql Server函数全解<三>数据类型转换函数和文本图像函数

    阅读目录 一:数据类型转换函数 二:文本和图像函数 一:数据类型转换函数 在同时处理不同数据类型的值时,SQL Server一般会自动进行隐士类型转换.对于数据类型相近的值是有效的,比如int和flo ...

  3. JS 数据类型转换

    JS 数据类型转换 方法主要有三种 转换函数.强制类型转换.利用js变量弱类型转换. 1. 转换函数: js提供了parseInt()和parseFloat()两个转换函数.前者把值转换成整数,后者把 ...

  4. 使用变量 数据类型转换 逻辑控制语句(begin ...end; case...end; if...else; while)

    一:变量 变量分为局部变量和全局变量  (全局变量是系统自定的,是不可手动给值的,若想自己定义全局变量可考虑创建全局临时表!) 局部变量的定义:  declare @变量名  数据类型 (局部变量只能 ...

  5. Util应用程序框架公共操作类(三):数据类型转换公共操作类(扩展篇)

    上一篇以TDD方式介绍了数据类型转换公共操作类的开发,并提供了单元测试和实现代码,本文将演示通过扩展方法来增强公共操作类,以便调用时更加简化. 下面以字符串转换为List<Guid>为例进 ...

  6. Util应用程序框架公共操作类(二):数据类型转换公共操作类(源码篇)

    上一篇介绍了数据类型转换的一些情况,可以看出,如果不进行封装,有可能导致比较混乱的代码.本文通过TDD方式把数据类型转换公共操作类开发出来,并提供源码下载. 我们在 应用程序框架实战十一:创建VS解决 ...

  7. Util应用程序框架公共操作类(一):数据类型转换公共操作类(介绍篇)

    本系列文章将介绍一些对初学者有帮助的辅助类,这些辅助类本身并没有什么稀奇之处,如何能发现需要封装它们可能更加重要,所谓授之以鱼不如授之以渔,掌握封装公共操作类的技巧才是关键,我会详细说明创建这些类的动 ...

  8. Sql Server函数全解(三)数据类型转换函数和文本图像函数

    一:数据类型转换函数 在同时处理不同数据类型的值时,SQL Server一般会自动进行隐士类型转换.对于数据类型相近的值是有效的,比如int和float,但是对于其它数据类型,例如整型和字符类型,隐士 ...

  9. SpringMVC框架下数据的增删改查,数据类型转换,数据格式化,数据校验,错误输入的消息回显

    在eclipse中javaEE环境下: 这儿并没有连接数据库,而是将数据存放在map集合中: 将各种架包导入lib下... web.xml文件配置为 <?xml version="1. ...

随机推荐

  1. 初识——Vim

    有些东西吧,总是碰见,低头不见抬头见,但又不知道是什么.用来干嘛的?总是搞的心里痒痒.所以一定要学习一下. 近期一段时间,总是碰到一个词儿:VIM,在这儿看到了,我不理他,隔一会儿丫的又跑我眼睛里,总 ...

  2. oc17--点语法

    // // Person.h // day13 #import <Foundation/Foundation.h> @interface Person : NSObject { // @p ...

  3. day63-webservice 06.在web项目中发布以类的形式发布webservice

    真正用的时候都是需要部署在WEB服务器里面. 不能写主函数来发布了,需要借助于我们WEB. 4.配置web.xml, <!DOCTYPE web-app PUBLIC "-//Sun ...

  4. C - Ilya and Sticks(贪心)

    Problem description In the evening, after the contest Ilya was bored, and he really felt like maximi ...

  5. SQLServer inner join,left join,right join,outer join 备忘备忘

    LEFT JOIN LEFT JOIN 关键字会从左表那里返回所有的行,即使在右表中没有匹配的行. 即LEFT JOIN 的 ON 条件不会对数据行造成影响 RIGHT JOIN RIGHT JOIN ...

  6. 关于CI中的MVC以及扩展CI中的控制器

    MVC是一种设计模式模式,M(模型)—V(视图)—C(控制器): MVC的核心思想是强制开发者在进行项目开发时,将数据的输入,处理,输出分开编写: 1.入口文件:该文件是唯一一个给浏览器直接请求的脚本 ...

  7. 【Oracle】RAC集群中的命令

    数据库名称:racdb 节点名称:rac3.rac4 注:以下命令均在grid用户中执行 1.查看集群节点的状态: [grid@rac3 ~]$ crsctl check cluster [grid@ ...

  8. PythonOpenCV--Rtrees随机森林

    360确实很个性,哈哈,你个貔貅,只吃不吐! Rtrees介绍!参考链接:http://docs.opencv.org/modules/ml/doc/random_trees.html 原文链接:Py ...

  9. DDoS攻击与防范策略

    DDoS(Distributed Denial of Service,分布式拒绝服务)攻击的主要目的是让指定目标无法提供正常服务,甚至从互联网上消失,是目前最强大.最难防御的攻击之一. 按照发起的方式 ...

  10. 考考你对java多态的理解

    请看如下代码, 如果你能不运行得出正确答案, 那你真的超过99%的java程序员了. [本人属于最大头的那部分] public class A{ public String s = "A&q ...