spring Boot来开发Web应用,大部分使用的是Spring MVC的一些功能及特性。Spring MVC在对数据格式化时,提供了很多内部格式化工具来方便开发人员来对数据进行处理。
具体可以参考:http://blog.csdn.net/jrainbow/article/details/46709543。
同样Spring MVC也提供了一些接口让我们方便的扩展,自定义一些方法来处理数据。
我们这里就是使用Spring MVC的AnnotationFormatterFactory接口来实现字符串与Java.sql.Timestamp间的格式化。并使用Spring Boot的自动配置功能,将此格式化工具引入到我们的Spring Boot项目中。
1、自定义注解
package xyz.ibenben.parttime.common.formatter.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
* @TimestampFormat 注解类型
*
* Timestamp
*
* @author 潘广伟
* @Email p_3er@qq.com
* @Date 2015-1-28 上午9:59:52
*
* @version 1.0.0
*
*/
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface TimestampFormat {
}
我们先定义一个@TimestampFormat注解,当我们在实体类的属性或属性的getter方法中标上此注解的时候,Spring MVC会知道,此属性接收到的数据需要进行格式化。
如:下面Task实体类的startTime属性。
package xyz.ibenben.parttime.task.entity;
import java.io.Serializable;
import java.sql.Timestamp;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Transient;
import xyz.ibenben.parttime.common.formatter.annotation.TimestampFormat;
import xyz.ibenben.parttime.user.entity.Employer;
public class Task implements Serializable {
private static final long serialVersionUID = 522265566715251213L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String profession;
@Column(name = "employer_id")
private Integer employerId;
@Column(name = "location_id")
private Integer locationId;
@Column(name = "init_time")
private Timestamp initTime;
@TimestampFormat
@Column(name = "start_time")
private Timestamp startTime;
@Column(name = "low_hourly_wage")
private Double lowHourlyWage;
@Column(name = "hight_hourly_wage")
private Double hightHourlyWage;
private String descript;
private Integer state;
@Transient
private TaskSituation situation;
@Transient
private Employer employer;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getProfession() {
return profession;
}
public void setProfession(String profession) {
this.profession = profession;
}
public Integer getEmployerId() {
return employerId;
}
public void setEmployerId(Integer employerId) {
this.employerId = employerId;
}
public Timestamp getInitTime() {
return initTime;
}
public void setInitTime(Timestamp initTime) {
this.initTime = initTime;
}
public Timestamp getStartTime() {
return startTime;
}
public void setStartTime(Timestamp startTime) {
this.startTime = startTime;
}
public Double getLowHourlyWage() {
return lowHourlyWage;
}
public void setLowHourlyWage(Double lowHourlyWage) {
this.lowHourlyWage = lowHourlyWage;
}
public Double getHightHourlyWage() {
return hightHourlyWage;
}
public void setHightHourlyWage(Double hightHourlyWage) {
this.hightHourlyWage = hightHourlyWage;
}
public String getDescript() {
return descript;
}
public void setDescript(String descript) {
this.descript = descript;
}
public Integer getState() {
return state;
}
public void setState(Integer state) {
this.state = state;
}
public Employer getEmployer() {
return employer;
}
public void setEmployer(Employer employer) {
this.employer = employer;
}
public Integer getLocationId() {
return locationId;
}
public void setLocationId(Integer locationId) {
this.locationId = locationId;
}
public TaskSituation getSituation() {
return situation;
}
public void setSituation(TaskSituation situation) {
this.situation = situation;
}
}
2、实现AnnotationFormatterFactory
package org.springframework.format;
public interface AnnotationFormatterFactory<A extends Annotation> {
Set<Class<?>> getFieldTypes();
Printer<?> getPrinter(A annotation, Class<?> fieldType);
Parser<?> getParser(A annotation, Class<?> fieldType);
}
上面是AnnotationFormatterFactory接口的定义:
- getFieldTypes() 返回的是所有会用于属性上说明需要格式化的注解集合。
- getPrinter() 返回的是此格式化工厂使用到的格式化工具。
- getParser()返回的是反(逆)格式化的工具。
java.sql.Timestamp的格式化处理如下:
- 注解集合
Set<Class<?>> set = new HashSet<Class<?>>();
set.add(Timestamp.class);
this.fieldTypes = set;
public Set<Class<?>> getFieldTypes() {
return fieldTypes;
}
- 格式化工具
/**
* 字符转Timestamp类型格式化类
*
* TimestampFormatter
*
* @author 潘广伟
* @Email p_3er@qq.com
* @Date 2015-1-28 上午11:34:35
*
* @version 1.0.0
*
*/
private class TimestampFormatter implements Formatter<Timestamp>,Serializable{
private static final long serialVersionUID = -818656464607971661L;
public String print(Timestamp value, Locale locale) {
if(value == null) {
return "";
}
return value.toString();
}
public Timestamp parse(String value, Locale locale) throws ParseException {
if(value.length() == 16){
value = new StringBuffer(value).append(":00").toString();
}
return Timestamp.valueOf(value);
}
}
此工具同时包含Printer及Parser。
public Parser<Timestamp> getParser(TimestampFormat annotation, Class<?> fieldType) {
return formatter;
}
public Printer<Timestamp> getPrinter(TimestampFormat annotation, Class<?> fieldType) {
return formatter;
}
完整代码:
package xyz.ibenben.parttime.common.formatter;
import java.io.Serializable;
import java.sql.Timestamp;
import java.text.ParseException;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import org.springframework.format.AnnotationFormatterFactory;
import org.springframework.format.Formatter;
import org.springframework.format.Parser;
import org.springframework.format.Printer;
import xyz.ibenben.parttime.common.formatter.annotation.TimestampFormat;
/**
* Timestamp注解格式化工厂
*
* TimestampFormatAnnotationFormatterFactory
*
* @author 潘广伟
* @Email p_3er@qq.com
* @Date 2015-1-28 上午10:20:47
*
* @version 1.0.0
*
*/
public class TimestampFormatAnnotationFormatterFactory implements AnnotationFormatterFactory<TimestampFormat>{
private final Set<Class<?>> fieldTypes;
private final TimestampFormatter formatter;
public TimestampFormatAnnotationFormatterFactory() {
Set<Class<?>> set = new HashSet<Class<?>>();
set.add(Timestamp.class);
this.fieldTypes = set;
this.formatter = new TimestampFormatter();
}
public Set<Class<?>> getFieldTypes() {
return fieldTypes;
}
public Parser<Timestamp> getParser(TimestampFormat annotation, Class<?> fieldType) {
return formatter;
}
public Printer<Timestamp> getPrinter(TimestampFormat annotation, Class<?> fieldType) {
return formatter;
}
/**
* 字符转Timestamp类型格式化类
*
* TimestampFormatter
*
* @author 潘广伟
* @Email p_3er@qq.com
* @Date 2015-1-28 上午11:34:35
*
* @version 1.0.0
*
*/
private class TimestampFormatter implements Formatter<Timestamp>,Serializable{
private static final long serialVersionUID = -818656464607971661L;
public String print(Timestamp value, Locale locale) {
if(value == null) {
return "";
}
return value.toString();
}
public Timestamp parse(String value, Locale locale) throws ParseException {
if(value.length() == 16){
value = new StringBuffer(value).append(":00").toString();
}
return Timestamp.valueOf(value);
}
}
}
3、配置
Spring MVC中的配置:
<bean class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="formatters">
<list>
<bean class="com.benben.timetable.common.formatter.TimestampFormatAnnotationFormatterFactory"/>
</list>
</property>
</bean>
如果我们既想使用Spring Boot MVC那么便捷的开发,又想获得额外的一些MVC配置,如interceptors, formatters, view controllers等的话,可以使用继承WebMvcConfigurerAdapter来加入这些配置。并使用@Configuration来交由Spirng Boot来自动配置。
如我们要在Spring Boot项目中使用格式化功能,重写WebMvcConfigurerAdapter的addFormatters方法。
package xyz.ibenben.parttime.common.configure;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import xyz.ibenben.parttime.common.formatter.TimestampFormatAnnotationFormatterFactory;
@Configuration
public class SpringConfig extends WebMvcConfigurerAdapter{
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addFormatterForFieldAnnotation(new TimestampFormatAnnotationFormatterFactory());
super.addFormatters(registry);
}
}