`
noble510520
  • 浏览: 56589 次
  • 性别: 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类型转换.md

    在Spring 3.1之前的版本中,如果需要对特定类型的参数进行格式化或者转换,可以使用`@InitBinder`注解来注册一个自定义的编辑器(`CustomEditor`)或转换器(`Converter`)。下面是一个例子: ```java import org....

    springmvc自定义属性编辑器和参数解析器

    属性编辑器(PropertyEditor)是Java Bean规范的一部分,它允许我们在程序中将一种类型的数据转换为另一种类型。在Spring MVC中,当控制器方法接收请求参数时,如果请求参数与方法参数类型不匹配,Spring会尝试使用...

    详解SpringMVC注解@initbinder解决类型转换问题

    SpringMVC 注解 @InitBinder 解决类型转换问题 在使用 SpringMVC 框架时...使用 @InitBinder 注解和 WebDataBinder 类可以解决 SpringMVC 中的类型转换问题,并提供了灵活的自定义编辑器机制,以满足不同的业务需求。

    springMVC三种数据转换的Demo

    然后需要在配置中启用该转换器: ```java @Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter { @Override public void addFormatters(FormatterRegistry registry) { ...

    SpringMVC demo

    SpringMVC 是 Spring 框架的一部分,它是一个用于构建 Web 应用程序的轻量级、模型-视图-控制器(MVC)框架。SpringMVC 提供了丰富的功能,使开发者能够轻松地处理 HTTP 请求,管理应用程序的业务逻辑,并将数据呈现...

    百度编辑器(修改版)-适用springmvc

    在IT行业中,集成富文本编辑器到Web应用是常见的需求,尤其在内容管理、论坛、博客等场景下。本文将详细讲解如何在Spring MVC框架中整合百度编辑器(修改版),以便更好地服务于后端数据处理。 **百度编辑器...

    maven项目springMVC demo

    Eclipse 4.5版本提供了对Java 8的支持,以及改进的代码编辑器和调试器,使得项目开发更加便捷。 3. **Tomcat6**:Apache Tomcat是一个开源的Servlet容器,实现了Java Servlet和JavaServer Pages(JSP)规范,用于...

    springmvc高级.docx

    2. **数据回显**:数据回显是指在表单提交后,如果验证失败或者需要重新编辑,将原来的输入值回显到表单中。Spring MVC通过模型属性和视图模型实现这一点。当出现错误时,之前的表单数据会存储在模型中,并在视图...

    springmvc+bootstrap+jsqumbile

    标题“springmvc+bootstrap+jsqumbile”表明这是一个关于使用Spring MVC框架、Bootstrap前端UI库以及jqGrid数据展示组件的项目。这三个技术是构建现代Web应用的常见组合,Spring MVC用于后端处理,Bootstrap用于前端...

    使用Eclipse构建Maven的SpringMVC项目

    总结,使用Eclipse构建Maven的SpringMVC项目涉及以下几个关键步骤:安装和配置Eclipse与Maven插件,创建动态Web项目,转换为Maven项目,配置pom.xml,编写SpringMVC代码,以及构建和部署项目。这个过程有助于我们...

    Java在线考试系统 SpringMVC实现.zip

    2. 视图解析器如InternalResourceViewResolver将控制器返回的逻辑视图名转换为实际的JSP页面。 3. Service层作为业务接口,封装了具体的操作,与DAO层交互。 4. DAO层利用Hibernate的Session接口进行数据库操作,...

    springmvc+mybatis 云笔记

    SpringMVC支持JSON数据格式的交换,可以通过Jackson或Gson库将Java对象转换为JSON,然后通过Ajax发送到服务器,实现无刷新的数据交互。在Controller中,可以使用`@ResponseBody`注解将处理结果直接作为HTTP响应体...

    springmvc接收参数为日期类型

    在上述代码中,`CustomDateEditor`是一个自定义的日期编辑器,它会按照指定的`SimpleDateFormat`格式解析日期字符串。 2. **使用`@DateTimeFormat`注解** 如果你只是需要处理某个特定方法的日期参数,可以使用...

    SpringMVC的@InitBinder参数转换代码实例

    例如,我们可以使用@InitBinder注解来指定要绑定的参数,并注册自定义的编辑器,用于将请求参数转换为对应的类型。此外,@InitBinder注解也可以用于解决前端传递的日期参数验证异常。 五、结论 本文主要介绍了...

    一个可以直接运行的基于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 学习笔记

    此外,还可以使用属性编辑器(PropertyEditor)进行类型转换,比如将字符串转换为整数或浮点数。 为了处理多个请求,Spring MVC 提供了 `MultiActionController` 类,该类允许你为每个请求定义一个方法。方法签名...

    SpringMVC 数据绑定实例详解

    这些编辑器会将请求参数中的多个值转换为集合或 Map 类型。例如,如果有多个同名的请求参数,它们会被转换为一个 List 对象。 此外,SpringMVC 还支持数据验证。我们可以使用 JSR-303 或 Hibernate Validator 规范...

Global site tag (gtag.js) - Google Analytics