• 数据类型转换简介
  • 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)         转换器

  1. package com.inspur.converter;
  2.  
  3. import java.util.regex.Matcher;
  4. import java.util.regex.Pattern;
  5. import org.springframework.core.convert.converter.Converter;
  6. import org.springframework.util.StringUtils;
  7. import com.inspur.pojo.PhoneNumberModel;
  8.  
  9. public class StringToPhoneNumberConverter implements Converter<String, PhoneNumberModel> {
  10. Pattern pattern = Pattern.compile("^(\\d{3,4})-(\\d{7,8})$");
  11.  
  12. public PhoneNumberModel convert(String source) {
  13. if (!StringUtils.hasLength(source)) {
  14. // ①如果source为空返回null
  15. return null;
  16. }
  17. Matcher matcher = pattern.matcher(source);
  18. if (matcher.matches()) {
  19. // ②如果匹配进行转换
  20. PhoneNumberModel phoneNumber = new PhoneNumberModel();
  21. phoneNumber.setAreaCode(matcher.group(1));
  22. phoneNumber.setPhoneNumber(matcher.group(2));
  23. return phoneNumber;
  24. } else {
  25. // ③如果不匹配转换失败
  26. throw new IllegalArgumentException(String.format(
  27. "类型转换失败,需要格式[010-12345678],但格式是[%s]", source));
  28. }
  29. }
  30. }

2)         使用的model

  1. public class PhoneNumberModel {
  2. private String areaCode;//区号
  3. private String phoneNumber;//电话号码
  4. //省略get/set……
  5. }

3)         简单的测试代码

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

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

4)         集成到Spring Web MVC环境

  1. <!-- 注册ConversionService实现和自定义的类型转换器 -->
  2. <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
  3. <property name="converters">
  4. <list>
  5. <bean class="com.inspur.converter.StringToPhoneNumberConverter" />
  6. </list>
  7. </property>
  8. </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. js动态创建表格------Day59

    刚刚不知道怎么回事,CSDN博客一直打不开,就在博客园完毕了今天的记录,结果临关机,登录了下.发现又好了,就再多花个几分钟转下吧,也无论到底在意的是什么了,权当强迫症了... 前几天记录了动态的加入一 ...

  2. 编写MyLayer,2 锚点,3 精灵的创建,4 zorder

     1 编写MyLayer 头文件:MyLayer.h #include "cocos2d.h" USING_NS_CC;   //代表的是: using namespace c ...

  3. Opencv绘制最小外接矩形、最小外接圆

    Opencv中求点集的最小外结矩使用方法minAreaRect,求点集的最小外接圆使用方法minEnclosingCircle. minAreaRect方法原型: RotatedRect minAre ...

  4. css3 animate写的超炫3D转换

    上一篇中介绍了animate的基本的属性,这一篇讲的则是关于animate以及transforms的使用 <!DOCTYPE html><html lang="en&quo ...

  5. 26. Remove Duplicates from Sorted Array[E]删除排序数组中的重复项

    题目 Given a sorted array nums, remove the duplicates in-place such that each element appear only once ...

  6. ACM_支离破碎(递推dp)

    支离破碎 Time Limit: 4000/2000ms (Java/Others) Problem Description: 远古时期有一位魔王想向一座宫殿里的公主求婚.为了考验魔王的智力,太后给了 ...

  7. C#操作Mysql类

    using System;using System.Collections.Generic;using System.Text;using System.Data;using System.Text. ...

  8. zookeeper单机和奇数集群

    zookeeper单机和奇数集群 链接地址:https://www.cnblogs.com/lsdb/p/7297731.html

  9. 开发辅助 | 阿里图标库iconfont入门使用

    目前大多数的互联网公司,前端开发和UI设计师配合中,针对设计师给图的效果图,前端开发工程师不再像往常一样对于细小图标进行切图,取而代之的是引用阿里图标库(http://iconfont.cn/):简单 ...

  10. 如何使用fetch

    Fetch API  提供了一个 JavaScript接口,用于访问和操纵HTTP管道的部分,例如请求和响应.它还提供了一个全局fetch()方法,该方法提供了一种简单,合乎逻辑的方式来跨网络异步获取 ...