0061 Spring MVC的数据格式化--Formatter--FormatterRegistrar--@DateTimeFormat--@NumberFormat
Converter只完成了数据类型的转换,却不负责输入输出数据的格式化工作,日期时间、货币等虽都以字符串形式存在,却有不同的格式。
Spring格式化框架要解决的问题是:从格式化的数据中获取真正的数据,绑定数据,将处理完成的数据输出为格式化的数据。Formatter接口就是该框架最重要的接口
Converter主要是做Object与Object之间的类型转换,Formatter则是要完成任意Object与String之间的类型转换。前者适合于任何一层,而后者则主要用于web层
下面用Formatter接口完成0060中用converter完成的功能
先写个类实现Formatter接口
package net.sonng.mvcdemo.converter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import org.springframework.format.Formatter;
public class DateFormatter implements Formatter<Date> {
private String datePattern;
private SimpleDateFormat dateFormat;
public DateFormatter(String datePattern){
this.datePattern=datePattern;
dateFormat=new SimpleDateFormat(datePattern);
}
@Override
public String print(Date date,Locale locale){
System.out.println("Date转String类型执行中。。。。");
return dateFormat.format(date);
}
@Override
public Date parse(String source,Locale locale) throws ParseException{
try{
System.out.println("字符串转Date类型执行中。。。。");
return dateFormat.parse(source);
}catch(Exception ex){
ex.printStackTrace();
throw new IllegalArgumentException();
}
}
}
配置xml
<mvc:annotation-driven conversion-service="conversionService" />
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<!-- FormattingConversionServiceFactoryBean实现了ConversionService接口,具有类型转换和格式化的功能,既可以配置converters又可以配置formatters -->
<property name="formatters">
<list>
<bean class="net.sonng.mvcdemo.converter.DateFormatter" c:_0="dd-MM-yyyy" /> <!-- 注意日期格式日-月-年 -->
</list>
</property>
</bean>
访问index.html,输入数据,注意生日处按日月年的格式输入
使用FormatterRegistrar注册Formatter
要使用Formatter,除了上面的将其配置在FormattingConversionServiceFactoryBean
的formatters
属性中外,还可以像下面这样注册
写个类实现FormatterRegistrar
package net.sonng.mvcdemo.converter;
import org.springframework.format.FormatterRegistrar;
import org.springframework.format.FormatterRegistry;
public class MyFormatterRegistrar implements FormatterRegistrar { //实现FormatterRegistrar接口
private DateFormatter dateFormatter;
public void setDateFormatter(DateFormatter dateFormatter) { //setter
this.dateFormatter = dateFormatter;
}
@Override
public void registerFormatters(FormatterRegistry registry) {
registry.addFormatter(dateFormatter); //注册给定的formatter
}
}
配置xml
<mvc:annotation-driven conversion-service="conversionService" />
<bean id="dateFormatter" class="net.sonng.mvcdemo.converter.DateFormatter" c:_0="dd-MM-yyyy" /> <!-- 声明formatter的bean,提供给下面的MyFormatterRegistrar -->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="formatterRegistrars"> <!-- 这里可以配置converters,formatters,还可以配置formatterRegistrars -->
<set>
<bean class="net.sonng.mvcdemo.converter.MyFormatterRegistrar" p:dateFormatter-ref="dateFormatter" />
</set>
</property>
</bean>
Spring提供的一些Formatter实现
实际上,Spring自身已经将DateFormatter写好了,位于org.springframework.format.datetime包下
另外在org.springframework.format.number包下面还提供了三个用于数字对象格式化的实现类
----NumberFormatter:用于数字类型
----CurrencyFormatter:用户货币类型
----PercentFormatter:用于百分数数字类型
用注解配置Formatter
先写个index.html,分别测试日期、整数、百分数、货币类型
<!DOCTYPE html>
<html>
<head>
<title>Spring MVC的数据类型转换</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="resources/jquery-3.1.0.js"></script>
<script type="text/javascript" src="resources/json2.js"></script>
</head>
<body>
<form action="register" method="post">
日期类型:<input type="text" name="birthday" /> <br><br>
整数类型:<input type="text" name="total" /> <br><br>
百分数类型:<input type="text" name="discount" /><br><br>
货币类型:<input type="text" name="money" /><br><br>
<input type="submit" value="提交" />
</form>
</body>
</html>
实体类User,注解就加在该类的实例变量上
package net.sonng.mvcdemo.entity;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.NumberFormat;
import org.springframework.format.annotation.NumberFormat.Style;
public class User {
@DateTimeFormat(pattern="dd-MM-yyyy") //注解加在实例变量上
private Date birthday;
@NumberFormat(style=Style.NUMBER,pattern="#,###") //说是这两个属性互斥,怎么可以同时出现呢?
private int total;
@NumberFormat(style=Style.PERCENT)
private double discount;
@NumberFormat(style=Style.CURRENCY)
private double money;
//。。。。。。。
}
controller
package net.sonng.mvcdemo.controller;
import net.sonng.mvcdemo.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class UserController {
@RequestMapping("/register")
public String register(User user,Model model){
model.addAttribute("user", user);
return "result";
}
}
result.jsp
<%@page pageEncoding="utf-8"
contentType="text/html;charset=utf-8" %>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试AnnotationFormatterFactory</title>
</head>
<body>
<h3>测试表单数据格式化</h3>
<form:form modelAttribute="user" method="post" action="" >
<table>
<tr>
<td>日期类型:</td>
<td><form:input path="birthday"/></td>
</tr>
<tr>
<td>整数类型:</td>
<td><form:input path="total"/></td>
</tr>
<tr>
<td>百分数类型:</td>
<td><form:input path="discount"/></td>
</tr>
<tr>
<td>货币类型:</td>
<td><form:input path="money"/></td>
</tr>
</table>
</form:form>
</body>
</html>
输入:
输出:
org.springframework.format.annotation包下有两个注解:@DateTimeForamt和@NumberFormat
@DateTimeFormat
可以注释java.util.Date, java.util.Calendar, java.lang.Long等时间类型的变量,拥有以下三个互斥属性
----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,通过样式指定日期时间的格式,由两位字符组成,第一位表示日期,第二为表示时间
--------S:短日期时间样式
--------M:中日期时间样式
--------L:长日期时间样式
--------F:完整日期时间样式
---------:(短横线)忽略日期时间样式
@NumberFormat
可注释类似数字类型的实例变量,拥有两个互斥属性
----pattern:类型String,使用自定义的数字格式化串,如##,###表示50,000
----style:类型NumberFormat.Style,几个常用值:
--------Style.CURRENCY: 货币类型
--------Style.NUMBER: 正常数字类型
--------Style.PERCENT: 百分比类型
总结
数据格式化也包含了部分数据转换的内容
实现Formatter接口,重写print()与parse()方法,实现自定义的数据格式化
Spring MVC提供了几个格式化类:DateFormatter、NumberFormatter、CurrencyFormatter、PercentFormatter
利用注解@NumberFormat和@DateTimeFormat,注释在实体类的实例变量上,也可以实现日期、时间、数字的格式化