`

SpringMVC(十二)_数据绑定流程之数据格式化

阅读更多

       前言:本篇主要介绍SpringMVC的数据绑定流程中数据格式化的相关概念与用法

本篇文章重点关注以下问题:

  • SpringMVC的数据格式化架构
  • Spring内建的格式化转换器

  • 自定义格式转换器

1. SpringMVC的数据格式化架构

1.1 格式化转换器

       提供格式化转换的实现支持,对属性对象的输入/输出进行格式化,从其本质上讲依然属于 “类型转换” 的范畴。


       一共有如下两组四个接口:

 1. Printer接口

          格式化显示接口,将T 类型的对象根据Locale信息以某种格式进行打印显示(即返回字符串形式);

@FunctionalInterface
public interface Printer<T> {
	String print(T object, Locale locale);
}

 2. Parser接口

         解析接口,根据Locale信息解析字符串到T类型的对象,解析失败可以抛出java.text.ParseException或IllegalArgumentException异常即可。

@FunctionalInterface
public interface Parser<T> {
	T parse(String text, Locale locale) throws ParseException;
}

 3、Formatter接口

         格式化SPI接口,继承Printer 和Parser 接口,完成T类型对象的格式化和解析功能;

public interface Formatter<T> extends Printer<T>, Parser<T> {

}

 4、AnnotationFormatterFactory接口

         注解驱动的字段格式化工厂,用于创建带注解的对象字段的Printer 和Parser,即用于格式化和解析带注解的对象字段

public interface AnnotationFormatterFactory<A extends Annotation> { // 可以识别的注解类型
	Set<Class<?>> getFieldTypes();                           // 可以被A注解类型注解的字段类型集合
	Printer<?> getPrinter(A annotation, Class<?> fieldType); // 根据A注解类型和fieldType类型获取Printer
	Parser<?> getParser(A annotation, Class<?> fieldType);   // 根据A注解类型和fieldType类型获取Parser
}

        此接口返回用于格式化和解析被A注解类型注解的字段值的Printer 和Parser 。如JodaDateTimeFormatAnnotationFormatterFactory可以为带有@DateTimeFormat注解的java.util.Date字段类型创建相应的Printer 和Parser 进行格式化和解析。

 

1.2 格式化转换器注册器、格式化服务

       提供类型转换器注册支持,运行时类型转换API支持。


 其有两种接口:

1.FormatterRegistry

        格式化转换器注册器,用于注册格式化转换器(Formatter、Printer 和Parser、AnnotationFormatterFactory);

public interface FormatterRegistry extends ConverterRegistry {

	// 添加格式化转换器(Spring3.1 新增API)
	void addFormatter(Formatter<?> formatter);

	// 为指定的字段类型添加格式化转换器
	void addFormatterForFieldType(Class<?> fieldType, Formatter<?> formatter);

	// 为指定的字段类型添加Printer 和Parser
	void addFormatterForFieldType(Class<?> fieldType, Printer<?> printer, Parser<?> parser);

	// 添加注解驱动的字段格式化工厂AnnotationFormatterFactory
	void addFormatterForFieldAnnotation(AnnotationFormatterFactory<? extends Annotation> annotationFormatterFactory);

}

 

2. FormattingConversionService

         继承自ConversionService,运行时类型转换和格式化服务接口,提供运行期类型转换和格式化的支持。该实现类扩展了 GenericConversionService,因此它既具有类型转换的功能,又具有格式化的功能。FormattingConversionService 拥有一个FormattingConversionServiceFactroyBean 工厂类,后者用于在 Spring 上下文中构造前者。

         FormattingConversionService内部实现如下图所示:


       FormattingConversionService内部实现如上所示,当调用convert方法时:

  1. 若是S类型----->String:调用私有的静态内部类PrinterConverter,其又调用相应的Printer 的实现进行格式化;
  2. 若是String----->T类型:调用私有的静态内部类ParserConverter,其又调用相应的Parser 的实现进行解析;
  3. 若是A 注解类型注解的S 类型----->String:调用私有的静态内部类AnnotationPrinterConverter,其又调用相应的AnnotationFormatterFactory的getPrinter 获取Printer 的实现进行格式化;

  4. 若是String----->A 注解类型注解的T 类型:调用私有的静态内部类AnnotationParserConverter,其又调用相应的AnnotationFormatterFactory的getParser 获取Parser 的实现进行解析。

        注:S类型表示源类型,T类型表示目标类型,A表示注解类型。

        此处可以可以看出之前的Converter SPI 完成任意Object 与Object 之间的类型转换,而Formatter SPI 完成任意Object与String之间的类型转换。

 

2. Spring内建的格式化转换器

类名

说明

DateFormatter

java.util.Date<---->String(实现日期的格式化/解析)

NumberFormatter

java.lang.Number<---->String(实现通用样式的格式化/解析)

CurrencyFormatter

java.lang.BigDecimal<---->String(实现货币样式的格式化/解析)

PercentFormatter

java.lang.Number<---->String(实现百分数样式的格式化/解析)

NumberFormatAnnotationFormatterFactory

@NumberFormat注解类型的数字字段类型<---->String

①通过@NumberFormat指定格式化/解析格式

②可以格式化/解析的数字类型:Short、Integer、Long、Float、Double、BigDecimal、BigInteger

JodaDateTimeFormatAnnotationFormatterFactory

@DateTimeFormat注解类型的日期字段类型<---->String

          FormattingConversionServiceFactroyBean内部已经注册了NumberFormatAnnotationFormatterFactroy,JodaDateTimeFormatAnnotationFormatterFactroy。

3. 自定义格式转换器

      此处以解析/格式化AddressVo为例。字符串"江苏-南京" 格式化为 AddressVo:


 

1. 定义Formatter实现

public class AddressFormatter_ implements Formatter<AddressVo> {
    // 中文正则表达式
    Pattern pattern = Pattern.compile("^([\u4e00-\u9fa5]*)-([\u4e00-\u9fa5]*)$");
    
    @Override
    public String print(AddressVo address, Locale locale) {
        if(address == null) return "";
        return new StringBuilder().append(address.getProvince())
                                  .append("-")
                                  .append(address.getCity())
                                  .toString();
    }

    @Override
    public AddressVo parse(String text, Locale locale) throws ParseException {
        if(!StringUtils.hasLength(text)) return null;
        
        Matcher matcher = pattern.matcher(text);
        if(matcher.matches()) {
            String province = matcher.group(1); 
            String city     = matcher.group(2); 
            return new AddressVo(province, city);
        } else {
            throw new IllegalArgumentException();
        }
    }
}

 2. 定义解析/格式化字段的注解类型

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface AddressFormatter {

}

 3. 实现AnnotationFormatterFactory注解格式化工厂

public class AddressFormatAnnotationFormatterFactory implements AnnotationFormatterFactory<AddressFormatter> {

    private final AddressFormatter_ formatter;
    
    public AddressFormatAnnotationFormatterFactory() {
        this.formatter = new AddressFormatter_();
    }
    
    //②指定可以被解析/格式化的字段类型集合
    @Override
    public Set<Class<?>> getFieldTypes() {
        Set<Class<?>> set = new HashSet<Class<?>>();
        set.add(AddressVo.class);
        return set;
    }
    
    @Override
    public Parser<?> getParser(AddressFormatter annotation, Class<?> fieldType) {
        return formatter;
    }

    @Override   
    public Printer<?> getPrinter(AddressFormatter annotation, Class<?> fieldType) {
        return formatter;
    }
}

 4. 对实体类添加注解

@AddressFormatter
private AddressVo address;

 5. 注册自定义转换器

<!-- 配置 ConversionService -->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <property name="formatters">
        <set>
            <bean class="com.wj.web.formatters.AddressFormatAnnotationFormatterFactory"></bean>
        </set>
    </property>
</bean>

 

4. 简述Spring內建常用格式化注解用法

1.@DateTimeFormat

        @DateTimeFormat 注解可对java.util.Date、java.util.Calendar、java.long.Long 时间类型进行标注:

  • pattern 属性:类型为字符串。指定解析/格式化字段数据的模式,如:”yyyy-MM-dd hh:mm:ss”;
  • iso 属性:类型为 DateTimeFormat.ISO。指定解析/格式化字段数据的ISO模式,包括四种:ISO.NONE(不使用)  默认、ISO.DATE(yyyy-MM-dd) 、ISO.TIME(hh:mm:ss.SSSZ)、ISO.DATE_TIME(yyyy-MM-dd hh:mm:ss.SSSZ);
  • style 属性:字符串类型。通过样式指定日期时间的格式,由两位字符组成,第一位表示日期的格式,第二位表示时间的格式:S:短日期/时间格式、M:中日期/时间格式、L:长日期/时间格式、F:完整日期/时间格式、-:忽略日期或时间格式;

2. @NumberFormat

        可对类似数字类型的属性进行标注,它拥有两个互斥的属性:

  • style:类型为 NumberFormat.Style。用于指定– 样式类型,包括三种:Style.NUMBER(正常数字类型)、Style.CURRENCY(货币类型)、 Style.PERCENT(百分数类型);
  • pattern:类型为 String,自定义样式, 如patter="#,###";

3. 示例

@NumberFormat(pattern="#,####,####.#")
private double salary;
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date   birth;
 

 

代码下载来源:http://super-wangj.iteye.com/blog/2388430

 

  • 大小: 58.6 KB
  • 大小: 128.3 KB
  • 大小: 55.2 KB
  • 大小: 7.7 KB
  • 大小: 6.6 KB
分享到:
评论

相关推荐

    跟我学SpringMVC 教程

    在线版目录 第一章 Web MVC简介 第二章 Spring MVC入门 ...第七章 注解式控制器的数据验证、类型转换及格式化 SpringMVC数据格式化 第七章 注解式控制器的数据验证、类型转换及格式化 SpringMVC数据验证

    跟我学SpringMVC

    在线版目录 第一章 Web MVC简介 第二章 Spring MVC入门 ...第七章 注解式控制器的数据验证、类型转换及格式化 SpringMVC数据格式化 第七章 注解式控制器的数据验证、类型转换及格式化 SpringMVC数据验证

    SpringMVC——处理器方法参数的处理.docx

    2、DataBinder 首先调用Spring Web环境中的ConversionService组件,进行数据类型转换和格式化等操作,将ServletRequest中的信息填充到形参对象中; 3、DataBinder 然后调用Validator组件对已经绑定了请求消息数据的形参...

    springmvc demo

    Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC...提供了非常灵活的数据验证、格式化和数据绑定机制;提供了强大的约定大于配置(惯例优先原则)的契约式编程支持。

    springMVC 实战指南

    SpringMVC 3.0实战指南,包括框架简介,HTTP请求地址映射,HTTP请求数据的绑定,数据转换、格式化、校验,数据模型控制,试图及解析器等

    SpringMVC学习指南.pdf

    全书共计12章,分别从Spring框架、模型2和MVC模式、Spring MVC介绍、控制器、数据绑定和表单标签库、传唤器和格式化、验证器、表达式语言、JSTL、国际化、上传文件、下载文件多个角度介绍了Spring MVC。除此之外,...

    SpringMVC大威天龙.docx

    SpringMVC是Spring提供的一个强大而灵活的Web框架 借助于注解 SpringMVC提供了几乎是POJO的开发模式 使得控制器的...4. 功能强大的数据验证 格式化 绑定机制 5. 约定大于配置的契约式编程支持 基于注解的零配置支持等等

    spring杂谈 作者zhang KaiTao

    1.23 扩展SpringMVC以支持绑定JSON格式的请求参数 1.24 扩展SpringMVC以支持绑定JSON格式的请求参数 1.25 在应用层通过spring特性解决数据库读写分离 1.26 context:component-scan扫描使用上的容易忽略的use-default...

    Spring MVC 3.0实战指南.ppt

    4、数据转换、格式化、校验 5、数据模型控制 6、视图及解析器 7、其它 目录: Spring MVC 3.0新特性 Spring MVC框架结构 Spring MVC框架结构 框架的实现者 目录 HTTP请求映射原理 Spring MVC进行映射的依据 通过URL...

    Spring MVC学习指南 第2版 高清版

    全书共包括13章和5个附录,分别从Spring框架、模型2和MVC模式、Spring MVC介绍、控制器、数据绑定和表单标签库、转换器和格式化、验证器、表达式语言、JSTL、国际化、上传文件、下载文件以及应用测试等多个角度介绍...

    spring mvc 3.2 参考文档

    Spring的数据绑定是高度灵活的: 例如,它把类型不匹配当做验证错误,这样就可以算作应用程序错误,而不是系统错误。因此你不需要简单的重复拷贝您的业务对象的属性,表单对象中的非类型化的字符串只是处理无效的...

    Spring MVC学习指南

    1.Spring和SpringMVC简介 2.模型2和MVC模式 3.数据绑定和表单标签库 4.转换器,格式化和验证器 5.表达式语言 6.JSTL 7.国际化 8.上传文件和下载文件 9.丰富的示例可供读者练习和参考

    Java-Interview-Offer

    java工程师修炼之道 阶段一:java基础 java基础语法 ...数据绑定 MyBatis 缓存机制 运行原理 JPA 注解 映射 SpringData 玛文 本地仓库&中央仓库 继承与聚合 吉特 常用操作命令 工作流 Linux常用命令

    Spring.MVC-A.Tutorial-Spring.MVC学习指南

    全书共计12章,分别从Spring框架、模型2和MVC模式、Spring MVC介绍、控制器、数据绑定和表单标签库、传唤器和格式化、验证器、表达式语言、JSTL、国际化、上传文件、下载文件多个角度介绍了Spring MVC。除此之外,...

    Spring MVC处理参数中的枚举类型通用实现方法

    主要给大家介绍了关于Spring MVC处理参数中的枚举类型通用实现方法的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起看看吧

    软件系统设计方案.pdf

    SpringMVC是使⽤了MVC设计思想的轻量级web框架,对web层进⾏解耦,与Spring⽆缝衔接,有着灵 活的数据验证,格式化,数据绑定机制;Mybatis中数据库的操作(sql)采⽤xml⽂件配置,解除了sql和代码的耦合提供映射标签...

    java猜数字源码-eweb4j-framework:简单的Java网络框架

    响应内容的格式 智能的HTTP 参数绑定 灵活可控的HTTP 参数验证 超级方便的文件上传下载 超级方便的视图数据传递 充血模型 声明式事务、事务模板、事务嵌套 丰富的DAO封装类 多数据源、表关联 简单的 IOC 容器 MVC、...

    CrapApi开源接口管理系统v1.0

    AngularJS有着诸多特性,最为核心的是:MVVM、模块化、自动化双向数据绑定、语义化标签、依赖注入等等。 Bootstrap-Twitter开源工具包 Bootstrap是Twitter推出的一个用于前端开发的开源工具包。它由Twitter的设计师...

    Spring.MVC-A.Tutorial-Spring.MVC学习指南.rar

    全书共计12章,分别从Spring框架、模型2和MVC模式、Spring MVC介绍、控制器、数据绑定和表单标签库、传唤器和格式化、验证器、表达式语言、JSTL、国际化、上传文件、下载文件多个角度介绍了Spring MVC。除此之外,...

Global site tag (gtag.js) - Google Analytics