我的编程空间,编程开发者的网络收藏夹
学习永远不晚

SpringBootJSON全局日期格式转换器实现方式

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

SpringBootJSON全局日期格式转换器实现方式

需求

前台有日期字符串的数据,提交到后台。后台实体类使用Date属性接收。
日期字符串有多种格式,需要用一个转换器将合法的日期字符串格式转换为Date类型。

分析

当前台的提交数据的Content-Typeapplication/json;charset=utf-8,后台使用@RequestBody来接收数据的时候,使用此转换方式。

一. 前期准备

1.1 日期正则注解

用来标记日期字符串所对应的正则表达式

import java.lang.annotation.*;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface DatePattern {
	
    String value();
}

1.2 日期格式定数

指定所有支持的日期格式

public final class DateFormatPart {

	@DatePattern("^\\d{4}$")
	public static final String YYYY = "yyyy";

	@DatePattern("^\\d{4}\\d{2}$")
	public static final String YYYYMM = "yyyyMM";

	@DatePattern("^\\d{4}/\\d{2}$")
	public static final String YYYYMM_SLASH = "yyyy/MM";

	@DatePattern("^\\d{4}\\d{1,2}\\d{1,2}$")
	public static final String YYYYMMDD = "yyyyMMdd";

	@DatePattern("^\\d{4}/\\d{2}/\\d{2}$")
	public static final String YYYYMMDD_SLASH = "yyyy/MM/dd";

	@DatePattern("[0-9]+\\u5e74[0-9]+\\u6708[0-9]+\\u65e5$")
	public static final String YYYYMMDD_JP = "yyyy年MM月dd日";

    @DatePattern("^\\d{4}\\d{1,2}\\d{1,2} \\d{1,2}:\\d{1,2}:\\d{1,2}$")
	public static final String YYYYMMDD_HHMMSS = "yyyyMMdd HH:mm:ss";

    @DatePattern("^\\d{4}/\\d{2}/\\d{2} \\d{1,2}:\\d{1,2}:\\d{1,2}$")
	public static final String YYYYMMDD_HHMMSS_SLASH = "yyyy/MM/dd HH:mm:ss";
}

1.3 日期转换工具类

  • 从日期格式定数类中获取所有的属性值和该属性上所标记的正则注解,通过反射来映射为map。
  • 如果有需要增删的日期格式的话,只需要修改日期格式定数即可,便于维护。
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public final class DateUtil {

    // 日期格式 <==> 正则的map,使用LinkedHashMap可以避免按照顺序匹配正则表达式
    private static final Map<String, String> datePatternMap = new LinkedHashMap<>();

    // 日期格式List
    private static final List<String> dateFormatList = new ArrayList<>();

    // 使用静态代码块,可以保证只初始化一次
    static {

        Class<DateFormatPart> dateFormatClass = DateFormatPart.class;
        // 获取所有的属性
        Field[] fields = dateFormatClass.getFields();
        for (Field field : fields) {

            // 获取属性上的注解
            DatePattern annotation = field.getAnnotation(DatePattern.class);
            if (ObjectUtils.isEmpty(annotation)) {
                continue;
            }

            //  强制让属性可以访问
            ReflectionUtils.makeAccessible(field);

            // 日期格式化字符串
            String dateFormatStr = "";
            try {
                // 获取当前属性所对应的属性值
                dateFormatStr = (String)field.get(dateFormatClass);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }

            dateFormatList.add(dateFormatStr);

            // 将该属性的属性值和属性上的正则表达式放到map中
            datePatternMap.put(dateFormatStr, annotation.value());
        }
    }
	
	// 用所有可能支持的格式将日期字符串转换为Date格式
    public static Date formatDateStrToDateAllFormat(String dateStr) {

        if (ObjectUtils.isEmpty(dateStr)) {
            return null;
        }

        try {
            for (Map.Entry<String, String> mapEntry : datePatternMap.entrySet()) {
				
				// 如果当前日期字符串不符合当前正则的话
                if (!dateStr.matches(mapEntry.getValue())) {
                    continue;
                }

                return DateUtil.formatStringToDate(dateStr, mapEntry.getKey());
            }
        } catch (ParseException e) {
            return null;
        }

        return null;
    }
	
	// 通过指定的格式将日期字符串转换为Date类型
    public static Date formatStringToDate(String dateStr, String format) throws ParseException {

        if (ObjectUtils.isEmpty(dateStr) || !dateFormatList.contains(format)) {
            return null;
        }

        SimpleDateFormat time = new SimpleDateFormat(format);
        return time.parse(dateStr);
    }
}

二. 方式1-继承DateDeserializer类,重写_parseDate方法

  • 该方式的要点是通过继承DateDeserializer类,然后重写_parseDate方法实现转换功能
  • 自定义的GlobalDateDeserializer类需要添加到自定义的SimpleModule模块中,然后将模块添加到ObjectMapper中,通过jackson来实现转换。
  • 通过设置ObjectMapper对象的setDateFormat方法来实现后台数据返回到前台时的Date转String的默认格式。
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.json.PackageVersion;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.deser.std.DateDeserializers.DateDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

@Configuration
public class CustomConfig {

    
    private static final class GlobalDateDeserializer extends DateDeserializer {

        @Override
        protected Date _parseDate(JsonParser jp, DeserializationContext context) throws IOException {

            return DateUtil.formatDateStrToDateAllFormat(jp.getText());
        }
    }

    @Bean("objectMapper")
    @Primary
    @ConditionalOnMissingBean
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {

        // 创建jackson对象
        ObjectMapper jackson = builder.createXmlMapper(false).build();

        
        jackson.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 禁用默认的「yyyy-MM-dd'T'HH:mm:ss.SSS」UTC类型
        jackson.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

         
        DateFormat dateFormat = new SimpleDateFormat(DateFormatPart.YYYYMMDD_HHMMSS_SLASH);
        jackson.setDateFormat(dateFormat);

        // 创建一个模块,指定该模块是用来解析 Date.class 类型数据的
        SimpleModule newModule = new SimpleModule("GlobalDateDeserializer", PackageVersion.VERSION);
        // 将我们创建的全局日期转换类添加到模块中,指定转换Date类型
        newModule.addDeserializer(Date.class, new CustomConfig.GlobalDateDeserializer());
        // 将该模块添加到jackson中
        jackson.registerModule(newModule);

        return jackson;
    }
}

三. 方式2-继承StdDateFormat类,重写方法

  • parse方法用来将日期字符串转换为Date(前台向后台传数据)
  • format方法用来将Date格式的数据转换为指定格式的字符串(后台向前台传数据)。
import java.text.FieldPosition;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;

import com.fasterxml.jackson.databind.util.StdDateFormat;

public class GlobalJsonDateConvert extends StdDateFormat {

    // 静态初始化final,共享
    public static final GlobalJsonDateConvert instance = new GlobalJsonDateConvert();

    // 日期字符串解析为日期
    @Override
    public Date parse(String dateStr, ParsePosition pos) {
        return getDate(dateStr);
    }

    @Override
    public Date parse(String dateStr) {
        return getDate(dateStr);
    }
	
	// 使用自定义的日期转换工具类将所有可能支持的日期字符串转换为Date格式
    private Date getDate(String dateStr) {
        return DateUtil.formatDateStrToDateAllFormat(dateStr);
    }
    
	
    @Override
    public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition){
        SimpleDateFormat sdf = new SimpleDateFormat(DateFormatPart.YYYYMMDD_HHMMSS_SLASH);
        return sdf.format(date, toAppendTo, fieldPosition);
    }

    @Override
    public GlobalJsonDateConvert clone() {
        super.clone();
        return new GlobalJsonDateConvert();
    }
}

3.1 MappingJackson2HttpMessageConverter方式

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

@Configuration
public class CustomConfig {

    // JSON格式 全局日期转换器配置
    @Bean
    public MappingJackson2HttpMessageConverter createMappingJackson2HttpMessageConverter() {

        
        MappingJackson2HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter();
        jacksonConverter.getObjectMapper().setDateFormat(GlobalJsonDateConvert.instance);

        return jacksonConverter;
    }
}

3.2 ObjectMapper方式

通过Jackson2ObjectMapperBuilder创建ObjectMapper对象,然后将我们定义的转换器GlobalJsonDateConvert放到ObjectMapper对象中

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

@Configuration
public class CustomConfig {

    @Bean("objectMapper")
    @Primary
    @ConditionalOnMissingBean
    public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
		
        ObjectMapper objectMapper = builder.build();
        objectMapper.setDateFormat(GlobalJsonDateConvert.instance);
        return objectMapper;
    }
}

3.3 Jackson2ObjectMapperBuilder方式

将我们定义的转换器GlobalJsonDateConvert放到Jackson2ObjectMapperBuilder对象中

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

@Configuration
public class CustomConfig {

    @Bean
    public Jackson2ObjectMapperBuilder objectMapper() {

        Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder = new Jackson2ObjectMapperBuilder();
        jackson2ObjectMapperBuilder.dateFormat(GlobalJsonDateConvert.instance);
        return jackson2ObjectMapperBuilder;
    }
}

四. 效果

⏹前台JS

// 向后台传输的json数据
const jsonData = {
	// ?待处理的日期字符串数据
    birthday: '2027年12月12日',
    nameAA: 'jiafeitian',
    hobby: '吃饭'
};

$.ajax({
    url: url,
    type: 'POST',
    // 对象转换为json字符串
    data: JSON.stringify(jsonData),
    contentType: "application/json;charset=utf-8",
    success: function (data, status, xhr) {
        console.log(data);
    }
});

⏹后台Form

import lombok.Data;
import java.util.Date;

@Data
public class Test15Form {

    private String name;

    private String hobby;

    private String address;
	
	// 用来接收的Date类型的数据
    private Date birthday;
}

?可以看到前台提交的日期字符串被转换为Date格式了

五. 总结

方式一中的1种方法和方式二中的3种方法,共计4中方法都可以实现全局日期格式转换器。
要点就是自定义日期转换的工具类用来处理各种可能的日期格式,并且将此工具类放到Jackson中的ObjectMapper对象中,上述4中方法的本质都是如此。

到此这篇关于SpringBoot JSON全局日期格式转换器的文章就介绍到这了,更多相关SpringBoot JSON日期格式转换内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

SpringBootJSON全局日期格式转换器实现方式

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

SpringBootJSON全局日期格式转换器实现方式

这篇文章主要介绍了SpringBootJSON全局日期格式转换器,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
2023-05-16

SpringBoot 表单提交全局日期格式转换器实现方式

这篇文章主要介绍了SpringBoot 表单提交全局日期格式转换器,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
2023-05-16

Hive日期格式转换方法总结

目录背景时间戳日期格式转换背景日期计算平时在业务取数时经常涉及到,但是数据库中经常存放着不同的日期格式,有的存放是时间戳、有的是字符串等,这时需要对其进行转换才能提取到准确的数据,这里介绍的均是hive里面的函数功能,以下内容均是业务的数
2022-06-23

MySQL函数date_format()日期格式转换的实现

一、在oracle中,当想把字符串为‘2011-09-20 08:30:45’的格式转化为日期格式,我们可以使用oracle提供的to_date函数。sql语句为:SELECT to_date('2011-09-
2022-08-12

linux shell实现转换输入日期的格式

对于用户输入日期的合法性检验,是个很重要的问题,这个例子是简单得取得用户输入的日期,并转换为相应的格式,但不完美,原因请看后文。#!/bin/sh # normdate -- Normalizes month field in date s
2022-06-04

vue实现将时间戳转换成日期格式

正文在Vue.js中,将时间戳转换为日期格式的方法包括:使用formatDate过滤器使用Moment.js库创建自定义过滤器使用计算属性最佳实践包括:使用一致的格式字符串考虑本地化缓存转换后的日期利用Vue.js的响应式系统
vue实现将时间戳转换成日期格式
2024-04-25

linux shell如何实现转换输入日期的格式

这篇文章给大家分享的是有关linux shell如何实现转换输入日期的格式的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。对于用户输入日期的合法性检验,是个很重要的问题,这个例子是简单得取得用户输入的日期,并转换为
2023-06-09

access日期格式转换的方法是什么

在Access中,可以使用Format函数来进行日期格式转换。下面是一个示例:1. 转换日期为特定格式:格式:Format(日期, "目标格式")示例:Format(#2021/01/01#, "yyyy-mm-dd") 返回 "2021-
2023-09-09

Vueelementel-table-column中对日期进行格式化方式(全局过滤器)

这篇文章主要介绍了Vueelementel-table-column中对日期进行格式化方式(全局过滤器),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-05-15

java中日期格式转换的方法有哪些

Java中日期格式转换的方法有以下几种:1. SimpleDateFormat类:通过指定的模式将日期转换为字符串,或者将字符串解析为日期。例如:```javaSimpleDateFormat sdf = new SimpleDateFor
2023-08-17

sqlserver字符串转日期格式怎么实现

在 SQL Server 中,可以使用 CONVERT 函数将字符串转换为日期格式。以下是一个示例:DECLARE @dateString VARCHAR(10) = '2022-03-15';DECLARE @da
sqlserver字符串转日期格式怎么实现
2024-04-09

PHP实现时间戳转日期格式的方法详解

标题:PHP实现时间戳转日期格式的方法详解在Web开发中,经常需要处理日期和时间数据,其中时间戳是一种常见的表示时间的方式。PHP作为一种常用的服务器端编程语言,提供了丰富的日期时间处理函数,可以方便地将时间戳转换为具体的日期时间格式。本
PHP实现时间戳转日期格式的方法详解
2024-03-08

PHP时间戳转换为日期格式的方法有哪些?

PHP时间戳是指从1970年1月1日 00:00:00(格林尼治标准时间)开始计算的秒数,是很常见的时间表示方式。在PHP中将时间戳转换为日期格式有多种方法,下面将介绍其中几种常用的方法,并附上具体的代码示例。方法一:使用date()函数
PHP时间戳转换为日期格式的方法有哪些?
2024-03-12

CentOS下使用LibreOffice实现文档格式的转换方式

项目需求,对上传的文档进行一些预处理,如果用户上传了doc格式的文档,需要将其处理为docx或者pdf格式,以便后续的流程对文档内容进行提取。 先是试了一下phpoffice/phpword这个包,发现其对doc的转换很不理想,这个包更适合
2022-06-04

MySQL将时间戳转换为年月日格式的实现

目录一、mysqlandroid中的日期和时间类型二、使用DATE_FORMAT函数进行转换在我们的项目开发过程中,经常需要将时间戳或日期时间字段转换为特定的格式,以满足特定的业务需求。zDoRFUNdQeMySQL作为广泛使用的关系型数据
MySQL将时间戳转换为年月日格式的实现
2024-08-31

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录