Spring MVC(3):数据转换 & 格式化

处理方法的数据绑定过程


Spring MVC 通过反射对目标处理方法签名进行分析,见请求消息绑定到处理方法的入参中,数据绑定的核心组件为 DataBinder;


Spring MVC 数据绑定过程如下:
  • Spring MVC 主框架将 ServletRequest 对象及处理方法入参对象实例传递到 DataBinder
  • DataBinder 调用装配在 Spring WebApplicationContext 的 ConversionService 组件进行数据转换、数据格式化,并将 ServletRequest 中的消息填充到入参对象中;
  • DataBinder 调用 Validator 组件对已经绑定请求详细数据的入参对象进行数据合法性校验,最终生成对象保存在 BindingResult (包含已经完成数据绑定的入参、校验错误对象)中;
  • Spring MVC 抽取 BindingResult 中的入参对象、校验错误对象,将他们赋予相应的方法入参;




数据转换


Spring 标准转接器装载

Spring 除了支持 Java 标准的转接器接口 java.beans.PropertyEditor ,同时本身在 org.springframework.core.convert 包中提供了一个通用的转接器模块,该模块的核心接口为 ConversionService (该接口的核心功能类似于 PropertyEditor,但是提供了上下文支持);

Spring 提供了一个工厂类 org.springframework.context.support. ConversionServiceFactoryBean 用于创建 ConversionService,该ConversionService 内建了多个转换器,可以完成大部分 Java 类型的转换工作,除了 将 String 对象转换为各种基础类型的对象外,还包括 String、Number、Array、Collection、Map、Properties、Object 之间的转换器

在 Spring 中装载 ConvesionService ,可以 Spring MVC上下文文件(如:“assad-servlet.xml ”)中配置以下 bean,该bean已经包含了多个标准转换器:
 
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean" />
<!--或者使用如下标签简化配置,上下2行配置都是相同的-->
<mvc:annotation-driven  />

自定义转接器的编写和装配

Spring 支持在向 ConversionService 注册自定义的转换器,对于自定义转换器的编写,支持2种方式:
  • 基于 org.springframework.core.convert.converter 包中相关接口实现(Converter<S,T>, GenericConverter, ConverterFactory)的转换器:
  • 基于 Java 标准 PropertyEditor 接口实现的编辑器

1)基于Spring Converter 实现的转换器

假设要将一个格式化的请求参数字符串直接转化为 User 对象,该请求字符串格式如下:
  "<userName>:<passowrd>:<credits>"
编写转换器类 StringToUserConverter
 
package site.assad.domain;
import org.springframework.core.convert.converter.Converter;
public class StringToUserConverter implements Converter<String,User> {
    //String Input Pattern:<username>:<password>:<credits>
    @Override
    public User convert(String source) {
        User user = new User();
        if(!source.isEmpty()){
            String[] items = source.trim().split(":");
            user.setName(items[0]);
            user.setPassword(items[1]);
            user.setCredits(Integer.parseInt(items[2]));
        }
        return user;
    }
}
在Spring-mvc配置文件 (如:”assad-servlet.xml“) 中注册该转换器:
 
<mvc:annotation-driven conversion-service="conversionService" />
<!--覆盖默认的 conversionServcie 实现-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean" >
    <property name="converters">
        <list>
            <bean class="site.assad.domain.StringToUserConverter" />  <!--注册自定义的转换器-->
        </list>
    </property>
</bean>
当装配好 StringToUserConverter 转换器后,就可以在控制类的任何处理方法使用该转换器,如下 UserController 中:
 
@RequestMapping(value="/handle9",params="user")
public String model9( @RequestParam("user") User user,ModelMap moddelMap){
    modelMap.put("user",user);
    return "showUser";
}
启动 Web 容器,发送 URL : "http://lcoalhost:8080/handle9?user=assad:2333:10",在逻辑视图  ”showUser“ 中可以获取到该请求参数字符串转化后的 User(name="assad",password="2333",credits=10);

2)基于Java标准 PropertyEditor 实现的编辑器

Spring 也支持 Java 标准的 PropertyEditor 编辑器,并提供了 @InitBinder 注解用于在控制器中添加自定义编辑器, WebBindingInitializer 用于装配全局范围使用的编辑器;
在控制器中添加自定义编辑器,使用@InitBinder 标注:
 
@Controller
@RequestMapping("/user")
public class UserController {
   @InitBinder
    public void initBinder(WebDataBinder binder){
        binder.registerCustomEditor(User.class,new UserEditor());  //向 UserContrller 中添加 UserEditor 编辑器
   }
   ....
}
在全局范围添加自定义编辑器:
实现 WebBindlingInitializer 接口,并在该实现类中注册 UserEditor
 
package site.assad.web;
public class MyBindingInitializer implements WebBindingInitializer{
  public void initBinder(WebDataBinder binder, WebRequest request) {
      binder.registerCustomEditor(User.class, new UserEditor());
   }
}
将该  WebBindlingInitializer  实现类绑定到 Spring-mvc 上下文:
 
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" >
      <property name="webBindingInitializer">
          <bean class="com.smart.web.MyBindingInitializer"/>
      </property>
</bean>

※Spring MVC 查找自定义转化器/编辑器 的优先顺序:
  • @InitBinder 装配的自定义编辑器;
  • ConversionService 装载的自定义转换器;
  • WeBindinginitializer 装载的自定义编辑器;




数据格式化


Spring MVC 支持在对数据绑定过程中,对数据进行格式化,在 org.springframework.fromat 包中提供了一个数据格式化框架,该框架最核心的接口为 Format<T> 接口,拓展于 Printer<T> 、Parser<T> 接口,Printer<T> 负责对象的格式化输出,Parser<T> 负责对象的格式化输入;
Spring MVC 的数据格式化是基于它提供的数据转换框架之上的;

启动 Spring MVC 数据格式化功能

启动 Spring MVC 格式化功能,需要 Spring-mvc 上下文中装配 FormattingConversionServiceFactoryBean ,该类是ConversionServcieFactory 的一个子类,如下:
 
<bean id="conversionService" class="org.springframework.context.support.FormattingConversionServiceFactoryBean" />
<!--或者如下-->
<mvc:annotation-driven/>
实际 <mvc:annotation-driven> 会自动装配一个 FormattingConversionServiceFactoryBean 的实例;
如果装配一个自定义的格式化转换器,装配方法如同装配自定义转化器,因为格式化转换器就是一种特殊的转化器;

使用驱动格式化注解

Spring-mvc 提供了一系列的注解,用于在domain领域对象中对属性进行格式化注解,这些注解一般用在领域对象的属性中;
常用的注解如下:

@DateTimeFormat
对日期时间对象进行格式化,如: java.util.Date、 java.util.Calendar、 java.long.Long、 Joda 时间类型;
含有以下互斥属性:
  • iso:类型为 DateTimeFormat.ISO,以下为常用可选值:
    • DateTimeFormat.ISO.DATE:           格式为 “yyyy-MM-dd”;
    • DateTimeFormat.ISO.DATE_TIME:格式为 “yyyy-MM-dd hh:mm:ss.SSSZ”;
    • DateTimeFormat.ISO.TIME:            格式为  “hh:mm:ss.SSSZ”;
    • DateTimeFormat.ISO.NONE:          表示不使用 ISO 格式的时间;
  • pattern:类型为 String,使用自定义的时间格式化串,如:“yyyy/MM/dd hh:mm:ss”;
  • style:类型为 String,通过样式指定时间日期的格式,由2位字符组成,第一位表示日期样式,第二位表示时间样式,如 “MM”,常用可选值:
    • S:短日期/时间格式,如 :“12/22/2017”,”13:27 PM“;
    • M:中日期/时间格式,如 :“12-Dec-2017”,”13:27:35 PM
    • L:长日期/时间格式,如 :“Decemenber 22,2017”,”13:27:35 PM EST
    • F:完整日期/时间格式,如 :“Friday,Decemenber 22,2017”,”13:27:35 o'clock PM EST
    • -:忽略日期/时间格式;

@NumberFromat 
对数字类型进行格式,由以下互斥属性:
  • pattern:类型为 String,使用自定义的数字格式化串,如:”##,###.##“
  • style:类型为 NumberFormat.Style ,以下为常用可选值:
    • NumberFormat.Style.CURRENCY:货币类型;
    • NumberFormat.Style.NUMBER:正常数字类型;
    • NumberFormat.Style.PERCENT:百分比数类型;

以下为一个使用实例:
领域对象 User
 
package site.assad.domain;
public class User1 {
    @DateTimeFormat(pattern="yyyy-MM-dd")
    private Date birthday;
    @NumberFormat(pattern="#,###.##")  //转换型如:“4,500.00”的String为long类型
    private long salary;
    
    .......
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值