`
noble510520
  • 浏览: 53749 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

SpringMVC类型转换器、属性编辑器

阅读更多

对于MVC框架,参数绑定一直觉得是很神奇很方便的一个东西,在参数绑定的过程中利用了属性编辑器、类型转换器

参数绑定流程

参数绑定:把请求中的数据,转化成指定类型的对象,交给处理请求的方法

编辑器转换器

  • 请求进入到DisptacherServlet,卸下请求中的数据
  • DisptacherServlet将请求中的数据发送给Controller
  • 获取Controller需要接收的参数类型,将参数类型和请求数据发送给DataBinder
  • DataBinder将参数类型和请求数据再发给TypeConverter,由TypeConverter装配成一个bean
  • TypeConverter根据bean中的成员类型,在PropertyEditorRegistry中查找已注册的PropertyEditor
  • PropertyEditor将数据setter进bean中的成员
  • TypeConverter将装配好的bean返回给DataBinder
  • DataBinder将装配bean交给处理请求的方法

在参数绑定的过程TypeConverter和PropertyEditor是最核心的数据转化成对象(非序列化)的过程TypeConverter负责将数据转化成一个beanPropertyEditor负责将数据转化成一个成员字段

属性编辑器

PropertiesEditor负责转化简单对象,因为http请求都是以字符串的形式,所以一般都是根据String来转换springmvc提供了很多默认的属性编辑器,在org.springframework.beans.propertyeditors包中,比如

微信截图_20160716120316

  • CustomBooleanEditor.class,String 转换 Boolean
  • CustomCollectionEditor.class,String 转换 Collection
  • CustomDateEditor.class,String 转换 Date
  • CustomMapEditor.class,String 转换 Map
  • CustomNumberEditor.class,String 转换  int、floot、double..

所有的属性编辑器都是继承PropertiesEditorSupport,默认的属性编辑器,Spring在启动的时候会自动加载除此之外,如果要装配的属性没有合适的编辑器,还可以自定义属性编辑器注册了自定义的属性编辑器之后,在CustomEditorConfigurer中注册,应用全局都可以使用这个属性编辑器,因为属性编辑器的工厂是全局作用域的

PropertiesEditor源码分析

PropertiesEditor.java

public class PropertiesEditor extends PropertyEditorSupport {
 //将String转成指定类型的对象
 @Override
 public void setAsText(String text) throws IllegalArgumentException {
  Properties props = new Properties();//Properties以key-value存值
   if (text != null) {
   try {
   //将String中表示的key=value或key:value信息,转化成Properties
   //key表示bean中字段名称
   //如果要转化成Date,则value是Date,String可以是"date=2012-12-12"的形式(date是字段名)
   props.load(new ByteArrayInputStream(text.getBytes("ISO-8859-1")));
  }
  catch (IOException ex) {
   throw new IllegalArgumentException(
   "Failed to parse [" + text + "] into Properties", ex);
   }
 }
  setValue(props);
 }
 //将old object转化成新object
 @Override
 public void setValue(Object value) {
   if (!(value instanceof Properties) && value instanceof Map) {
   Properties props = new Properties();
   props.putAll((Map<?, ?>) value);
   super.setValue(props);
 }
 else {
   //父类PropertyEditorSupport持有value对象,就是要转化后的对象
   super.setValue(value);
  }
 }
}

需要注意的是,setAsText通过一定格式的字符串来达到属性编辑的效果,"成员名称=value",或者是"成员名称:value",这样就会把value set到bean的指定成员中了编辑器中最重要的两个方法就是,setAsTest(String)和setValue(value),在这两个方法中完成从String——object,object——object

CustomDateEditor源码分析

CustomDateEditor是Spring的一个默认属性编辑器,负责将String转化成指定格式的Date对象同样他也是继承了PropertiesEditorSupport,重写了setAsTest方法

public class CustomDateEditor extends PropertyEditorSupport {
 //指定的date格式,如"yyyy-MM-dd"
 private final DateFormat dateFormat;
 //是否允许字符串为空
 private final boolean allowEmpty;
 //严格的日期长度
 private final int exactDateLength;

 public CustomDateEditor(DateFormat dateFormat, boolean allowEmpty) {
 //构造器方法
 }
 public CustomDateEditor(DateFormat dateFormat, boolean allowEmpty, int exactDateLength) {
 //构造器方法
 }
 //String转化成Dtae
 @Override
 public void setAsText(String text) throws IllegalArgumentException {
   //判断字符串是否为空
   if (this.allowEmpty && !StringUtils.hasText(text)) {
    setValue(null);
   }
   //判断字符串长度是否等于exactDateLength
   else if (text != null && this.exactDateLength >= 0 && text.length() != this.exactDateLength) {
     throw new IllegalArgumentException(
     "Could not parse date: it is not exactly" + this.exactDateLength + "characters long");
    }
   else {
   try {
     //将text格式化成Date对象
    setValue(this.dateFormat.parse(text));
   }
   catch (ParseException ex) {
     throw new IllegalArgumentException("Could not parse date: " + ex.getMessage(), ex);
   }
   }
   }
 //从Date输出String
 @Override
 public String getAsText() {
   Date value = (Date) getValue();
   //返回格式化的String
   return (value != null ? this.dateFormat.format(value) : "");
 }
}

从CustomDateEditor的源码可以看出,最重要的是重写setAsText方法,先校验下字符串格式符不符合要求,不符合要求就抛出异常,再根据字符串转成指定DateFormat的Date对象

类型转换器

刚刚讲的属性编辑器是用来填充bean中的属性的,类型转换器是负责从数据转换成一个bean所以在转换的过程中,需要属性编辑器帮忙填充属性,那么应该持有一堆属性编辑器(bean有各种各样的属性),那么持有一个PropertyEditorRegistry(一个属性编辑器工厂)就可以了类型转化器的实现不像属性编辑器那么多,主要就是三个

  • TypeConverter,类型转换的接口
  • TypeConverterSupport,类型转换的实现,持有一个TypeConverterDelegate,具体转换工作交给TypeConverterDelegate完成
  • TypeConverterDelegate,类型转换的委托类,所有类型转换的工作都由他完成

typeConverter

要实现的方法就只有convertIfNecessary,从源对象转换为目标对象

TypeConverterDelegate源码分析

因为转换工作是由TypeConverterDelegate负责的,源码太长,就看看转换那一部分的代码

/*
@Param propertyName bean的名称
@Param requiredType 需要的类型
@Param typeDescriptor 类型描述器
*/
public <T> T convertIfNecessary(String propertyName, Object oldValue, Object newValue,Class<T> requiredType, TypeDescriptor typeDescriptor) throws IllegalArgumentException {
 //从注册的属性编辑器中获取能编辑requiredType的属性编辑器
 PropertyEditor editor = this.propertyEditorRegistry.findCustomEditor(requiredType, propertyName);
 //...
 //使用属性编辑器去把oldValue转化成requiredType
 convertedValue = doConvertValue(oldValue, convertedValue, requiredType, editor);
 //...
 return convertedValue;
 }
/*
@Param propertyName bean的名称
@Param requiredType 需要的类型
@Param editor 属性编辑器
*/
 private Object doConvertValue(Object oldValue, Object newValue, Class<?> requiredType, PropertyEditor editor) {
   Object convertedValue = newValue;
   if (editor != null && !(convertedValue instanceof String)) {
   try {
     //转换数据
     editor.setValue(convertedValue);
     //得到转换后的数据
     Object newConvertedValue = editor.getValue();
     if (newConvertedValue != convertedValue) {
    convertedValue = newConvertedValue;
     editor = null;
    }
 }
   catch (Exception ex) {
     if (logger.isDebugEnabled()) {
     logger.debug("PropertyEditor [" + editor.getClass().getName() + "] does not support setValue call", ex);
    }
   }
 }
 Object returnValue = convertedValue;
 //...
 return returnValue;
 }
}

 查看原文:http://zswlib.com/2016/07/16/springmvc%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2%E5%99%A8%E3%80%81%E5%B1%9E%E6%80%A7%E7%BC%96%E8%BE%91%E5%99%A8/

0
0
分享到:
评论

相关推荐

    一个可以直接运行的基于SpringMVC的web框架1.1.12

    首页修改 dateformat.js 时间参数转换 SpringMVC配置文件集中 快递参数接口 1.1.4 des加解密字符串和文件 1.1.5 redis 加锁,redis升级成2.8.2 freemarker工具类 1.1.6 spring websocket 实现在线聊天 maven升级...

    SpringMVC基础上的web框架

    集成ueditor在线编辑器 1.0.11 地址联动 1.0.12 Excel工具类 Word工具类 Java NIO实现socket工具类 分布式session jdk升级到1.7 嵌入式redis服务(只支持linux) 1.0.13 修改默认的beanName生成策略,controller参数...

    基于SpringMVC的一个web框架

    集成ueditor在线编辑器 1.0.11 地址联动 1.0.12 Excel工具类 Word工具类 Java NIO实现socket工具类 分布式session jdk升级到1.7 嵌入式redis服务(只支持linux) 1.0.13 修改默认的beanName生成策略,controller参数...

    可以直接运行的基于SpringMVC的web框架示例,也可以直接当公司框架

    首页修改 dateformat.js 时间参数转换 SpringMVC配置文件集中 快递参数接口 1.1.4 des加解密字符串和文件 1.1.5 redis 加锁,redis升级成2.8.2 freemarker工具类 1.1.6 spring websocket 实现在线聊天 maven升级...

    基于IDEA+MySQL+Maven实现SSM框架整合

    基于IDEA+MySQL+Maven实现SSM框架整合,实现了多条件分页查询、新增、事务、自定义消息转换器、自定义编辑器、拦截器等功能 1. 数据库版本: mysql8.0.26 2. IDEA版本: idea2020 3. JDK版本: jdk1.8.1 4. Tomcat...

    Pdf--to--XML:PDF TO XML 转换器(Web 应用程序)

    PDF TO XML 转换器(Web 应用程序)使用的工具: JavaApache PDFBox API SpringMVC Jquery、AJAX、JS 和 CSS 引导框架STS(弹簧工具套件)描述: 该Web应用程序旨在解析pdf文件(Employess Payslip)并使用pdfbox ...

    和平之翼代码生成器SM Swing 0.8 单机版源码

    4)为SGS编辑器增加新增,保存等编辑器功能 5)生成器引擎的修错和改进 ==============PeaceWingSHC 0.7.11============== 1)将生成器改进到无垠式代码生成器0.8的水平 2)增加ActiveField名为deleted或delete自动反义...

    springboot-cms:基于Springboot,Spring,SpringMVC,Mybatis,FreeMarker,Bootstrap,Apache Shiro,Quartz,Email,MySQL等的内容管理系统

    文本编辑:百度UEditor编辑器 三,项目结构 trunk --------------------------------------------------------- 代码库 |- sql -------------------------------------------------------- 数据库建表语句以及初始化...

    Spring in Action(第2版)中文版

    3.4注册自定义属性编辑器 3.5使用spring的特殊bean 3.5.1后处理bean 3.5.2bean工厂的后处理 3.5.3配置属性的外在化 3.5.4提取文本消息 3.5.5程序事件的解耦 3.5.6让bean了解容器 3.6脚本化的bean 3.6.1给...

    JavaServer Faces 2.0完全参考手册(JSF2.0中文版) 1/2

    8.3.3 关联转换器与UI Component实例 8.3.4 转换器的生命周期 8.3.5 定制转换器 8.4 Faces验证系统 8.4.1 Long Range Validator 8.4.2 Double Range Validator 8.4.3 Length Validator 8.4.4 必需的工具Required ...

    JavaServer Faces 2.0完全参考手册(JSF2.0中文版).part1

    8.3.3 关联转换器与UI Component实例 8.3.4 转换器的生命周期 8.3.5 定制转换器 8.4 Faces验证系统 8.4.1 Long Range Validator 8.4.2 Double Range Validator 8.4.3 Length Validator 8.4.4 必需的工具Required ...

    基于Spring MVC的web框架 1.1.11

    集成ueditor在线编辑器 1.0.11 地址联动 1.0.12 Excel工具类 Word工具类 Java NIO实现socket工具类 分布式session jdk升级到1.7 嵌入式redis服务(只支持linux) 1.0.13 修改默认的beanName生成策略,controller参数...

    一个适合新手学习的电商项目

    富文本编辑器使用KindEditor 4.分页使用PageHelper插件,插件是基于mybatis的拦截器接口实现的 商品的展示功能: 1.分页插件的使用PageHelper。 2.easyUIDataGrid的使用 ### 前台系统 ### shop-rest(发布...

Global site tag (gtag.js) - Google Analytics