Spring MVC中的的数据转换与格式化

为什么需要数据转换与格式化

在实际操作中,经常会遇到表单中的日期字符串与JavaBean中的日期类型的属性需要自动转换的情况,而Spring MVC框架默认不支持这个格式转换,即在Spring MVC中时间数据无法实现自动绑定,必须要手动配置自定义数据类型的绑定。

在进行手动配置数据转换之前,需要先了解数据绑定的流程。

概述: Spring会根据请求方法签名的不同,将请求中的信息以一定的方式转换并绑定到请求方法的入参中。其实在请求信息真正到达处理方法之前,Spring MVC还完成了许多工作,包括数据转换、数据格式化,以及数据校验等。

数据绑定具体流程图

Spring MVC中的的数据转换与格式化_第1张图片

  • Spring MVC将ServletRequest对象以及处理方法的入参对象实例传递给DataBinder。

  • DataBinder调用ConversionService组件进行数据转换、格式化的工作,并将ServletRequest中请求信息填充到入参对象中。

  • 然后DataBinder再调用Validator组件对已经绑定了请求数据的入参对象进行数据合法性的验证,并最终生成数据绑定结果BindingResult对象。

解析:

(1)DataBinder:
数据绑定的核心组件,它在整个流程中起到核心调度的作用。

(2)ConversionService:

Spring类型转换体系的核心接口,可以利用org.springframework.context.support.ConversionServiceFactoryBean
在Spring的上下文定义一个 ConversionService 。Spring会自动识别出上下文中的 ConversionService ,在Bean属性配置和处理方法入参绑定时,使用它进行数据转换。所以在对于前台form表单中时间字符串到后台Date数据类型的转换问题,就可以通过 ConversionService 解决。

例:


注:在Spring MVC中 标签是简化配置,默认情况下,它会创建并注册一个默认的 DefaultAnnotationHandlerMapping (处理器映射) 与 AnnotationMethodHandlerAdapter(处理器适配器), 并且该注解还会注册一个 ConversionService 实例FormattingConversionServiceFactoryBean,所以无需手动配置上面代码。

(3)BindingResult:

BindingResult包含了已完成数据绑定的入参对象和相应的校验错误对象,Spring MVC会抽取BindingResult中的入参对象以及校验错误对象,将他们赋给处理方法的相应入参。

数据转换的两种方式

1、编写自定义转换器

Spring在 org.springframework.core.convert.converter.Converter 包中定义了最简单的Converter接口,它仅包括一个接口方法convert(),如图
Spring MVC中的的数据转换与格式化_第2张图片
Converter的作用就是将一种类型转换成另一种类型的对象。例如,用户输入的日期可能有多种形式,如"1987/1/1"、“1987-1-1” 等,这些都表示同一个日期。若希望Spring在将输入的日期绑定到Date时,使用不同的日期格式,则需要编写一个Converter,才能将字符串转换成日期。具体实现:首先需要创建一个
org.springframework.core.convert.converter.Converter 接口的Java类,然后将该实现了Converter接口的自定义转换器注册到ConversionServiceFactoryBean即可。

实现步骤如下:

  • 创建 StringtoDateConverter.java
package cn.smbms.tools;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.core.convert.converter.Converter;
/***
 * 字符串转日期格式工具类
 * @author 14062
 *
 */
public class StringToDateConverter implements Converter{

	private String datePattern;	//日期格式
	
	public StringToDateConverter(String datePattern){
		System.out.println("StringToDateConverter convert:"+datePattern);
		this.datePattern=datePattern;
	} 
	/**
	 * 将字符串转为日期格式并返回
	 */
	@Override
	public Date convert(String s) {
		Date date=null;
		try {
			date=new SimpleDateFormat(datePattern).parse(s);
			System.out.println("StringToDateConverter convert date:"+date);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return date;
	}
}

  • 装配自定义的ConversionService(将该实现了Converter接口的自定义转换器注册到ConversionServiceFactoryBean)
	
		
			
		
	
	
		
			
				
					
				
			
		
	

由于 标签会自动注册一个默认的 ConversionService ,现在由于我们需要注册一个自定义的 StringToDateConverter,因此需要显式定义一个 ConversionService 来覆盖 中的默认实现,通过配置 标签的 conversion-service 属性来完成。装配完成之后,就可以在任何控制器的处理方法中使用该转换器了。


2、使用@InitBinder装配自定义编辑器

对于数据转换,还有一种更灵活的方式,就是通过自定义的编辑器去实现数据的转换与格式化处理。具体实现步骤如下:

  • 创建BaseController.java,并标注@InitBinder注解
  • 修改Controller文件继承BaseController.java
package cn.smbms.controller;

import java.sql.Date;
import java.text.SimpleDateFormat;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;

public class BaseController {	
	/**
	 * 使用@InitBinder解决Spring MVC日期类型无法绑定的问题
	 * @param dataBinder
	 */
	@InitBinder
	public void initBinder(WebDataBinder dataBinder){
		System.out.println("initBinder====================");
		dataBinder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
	}
}

注: 标注了@InitBinder注解的方法会在控制器初始化时调用。在initBinder()方法体内,通过dataBinder的registerCustomEditor()方法注册一个自定义编辑器:

  • 第一个参数表示编辑器为日期类型(Date.class)
  • 第二个参数表示使用自定义的日期编辑器(CustomDateEditor),时间格式为yyyy-MM-dd,true表示该参数是否允许为空(时间格式参数)。

你可能感兴趣的:(SpringMVC)