这段时间在学习使用 SpringBoot 做项目,由于是初次使用,过程中遇到不少坑,学习过程中,时间允许的话会通过写文章方式记录我的填坑之旅。此刻的状态


springboot修改时区 springboot 日期转换_springboot修改时区

进入正题,我使用 SpringBoot 的时候,首先遇到的问题就是日期格式转换了。实体类中有时间类型的属性,往往会在前端与后台的数据交换中出现日期格式转换的问题,当然也有简单粗暴的方法,把属性设置为 String 类型,那就可以避免了,不过这就不符合我爱折腾的性格了,哈哈。

废话少说,开始折腾吧......

用户实体类 User.java 中有以下属性:


/**
 * 注册时间
 */
private Date userRegisterTime;

后台到前端的处理


未处理前,当从数据库查到数据在页面显示会是 2018-07-26T05:14:33.000+0000,有时候会是一串数字1478065615000, 处理后为:2018-07-26 13:14:33,并且格式可以设置。

具体解决方式

1、使用 SpringBoot 默认的 Json 数据转换 Jackson 时有两种方法可以设置

方法一:

时间类型的属性上添加注解,这样需要在每一个实体类中需要转换的属性中进行设置,有点麻烦,当然,不要忘了加上时区的设置,由于北京时间是东八区,所以使用 GMT-8。


@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")

方法二:

配置文件 application.properties 中全局处理,进行全局设置,也就不需要在每一个类中都设置了。


#配置Jackson时间格式转换
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8

2、使用阿里的 fastJson 进行 json 数据转换

时间类型的字段上添加,在每一个需要转换的字段中进行设置


@JSONField(format="yyyy-MM-dd HH:mm:ss")

其中 Jackson 和 fastJson 的配置使用方法之后再总结。

前端到后台的处理


当前端显示时间为 2018-07-26 13:14:33 时,是字符串,无法自动转为时间类型的数据,在编辑用户时就会报错:


Field error in object 'cblogUser' on field 'userRegisterTime': rejected value [2018-07-26 13:14:33]; 

codes[typeMismatch.cblogUser.userRegisterTime,typeMismatch.userRegisterTime,typeMismatch.java.util.Date,typeMismatch]; arguments[org.springframework.context.support.DefaultMessageSourceResolvable: codes [cblogUser.userRegisterTime,userRegisterTime]; 

arguments []; default message [userRegisterTime]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'userRegisterTime'; 

nested exception is org.springframework.core.convert.ConversionFailedException:Failed to convert from type [java.lang.String] to type [java.util.Date] for value '2018-07-26 13:14:33'; 

nested exception is java.lang.IllegalArgumentException]

从报错中可以看出,就是无法将 String 类型转为 Date 类型,这里配置全局时间转换器,实现前端向后台传数据时,时间格式的转换。

那么这个坑又该怎么填呢?

首先自定义 DateConverter.java,实现 Converter 接口:


package com.wenlincheng.cblog.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @ClassName: DateConverterConfig
 * @Description: TODO
 * @Author: Cheng
 * @Date: 2018/8/19 19:04
 * @Version: 1.0.0
 */
public class DateConverter implements Converter<String, Date> {

    private static final List<String> formarts = new ArrayList<>(4);
    static{
        formarts.add("yyyy-MM");
        formarts.add("yyyy-MM-dd");
        formarts.add("yyyy-MM-dd hh:mm");
        formarts.add("yyyy-MM-dd hh:mm:ss");
    }

    @Override
    public Date convert(String source) {
        String value = source.trim();
        if ("".equals(value)) {
            return null;
        }
        if(source.matches("^\\d{4}-\\d{1,2}$")){
            return parseDate(source, formarts.get(0));
        }else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}$")){
            return parseDate(source, formarts.get(1));
        }else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}$")){
            return parseDate(source, formarts.get(2));
        }else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}:\\d{1,2}$")){
            return parseDate(source, formarts.get(3));
        }else {
            throw new IllegalArgumentException("Invalid boolean value '" + source + "'");
        }
    }

    /**
     * 格式化日期
     * @param dateStr String 字符型日期
     * @param format String 格式
     * @return Date 日期
     */
    public  Date parseDate(String dateStr, String format) {
        System.out.println("时间格式化");
        Date date=null;
        try {
            DateFormat dateFormat = new SimpleDateFormat(format);
            date = dateFormat.parse(dateStr);
        } catch (Exception e) {

        }
        return date;
    }

}

定义配置类 Converter.java,注册时间类型转换器,在项目中我还使用了主配置类,这个类为从配置类,未加 @Configuration 注解,因此需要在主配置类中引入。


package com.wenlincheng.cblog.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;

import javax.annotation.PostConstruct;

/**
 * @ClassName: ConverterConfig
 * @Description: TODO
 * @Author: Cheng
 * @Date: 2018/8/19 19:16
 * @Version: 1.0.0
 */
//@Configuration
public class ConverterConfig {

    @Autowired
    private RequestMappingHandlerAdapter handlerAdapter;

    @PostConstruct
    public void initEditableAvlidation() {

        ConfigurableWebBindingInitializer initializer = (ConfigurableWebBindingInitializer)handlerAdapter.getWebBindingInitializer();
        if(initializer.getConversionService()!=null) {
            GenericConversionService genericConversionService = (GenericConversionService)initializer.getConversionService();

            // 注册日期类型转换器
            genericConversionService.addConverter(new DateConverter());
        }
    }
}

使用 @Import 注解在主配置类中引入如下:


package com.wenlincheng.cblog.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

/**
 * @ClassName: SpringConfiguration
 * @Description: TODO
 * @Author: Cheng
 * @Date: 2018/8/18 0:33
 * @Version: 1.0.0
 */
@Configuration
@Import({SecurityConfig.class,JacksonConfig.class,ConverterConfig.class})
public class SpringConfiguration {

}

这样,在 SpringBoot 中日期格式转换问题就解决了,有啥Bug还望指出。