SpringBoot JSON全局日期格式转换器如何实现

您所在的位置:网站首页 泰坦机甲手游下载安装 SpringBoot JSON全局日期格式转换器如何实现

SpringBoot JSON全局日期格式转换器如何实现

2024-07-17 18:32:14| 来源: 网络整理| 查看: 265

需求

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

分析

当前台的提交数据的Content-Type为application/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 datePatternMap = new LinkedHashMap(); // 日期格式List private static final List dateFormatList = new ArrayList(); // 使用静态代码块,可以保证只初始化一次 static { Class 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 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 { /* * 自定义的全局的日期转换解析类,需要继承jackson包中的DateDeserializer * 因为此类不会在别的地方使用了,因此直接使用内部类聚合到自定义的配置文件中 */ 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(); /* * DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES * 在进行序列化或者反序列化的时候, * JSON字符串中有一个字段,但是我们的对象没有这个字段的时候,该怎么处理 * 设置为true的时候,会抛出异常 * 设置为false,忽略异常继续处理 */ 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); /* * 设置序列化时的默认格式,即后台返回数据到前台的时候, * Date类型数据需要转换为的字符串格式 * 如果不进行指定的话,默认使用 yyyy-MM-dd'T'HH:mm:ss.SSS 格式 */ 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); } /* * 设置序列化时的默认格式,即后台返回数据到前台的时候, * Date类型数据需要转换为的字符串格式 * 如果不进行指定的话,默认使用 yyyy-MM-dd'T'HH:mm:ss.SSS 格式 */ @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得到的ObjectMapper, * 已经默认把 DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES 给关闭了 */ 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格式了

SpringBoot JSON全局日期格式转换器如何实现

以上就是SpringBoot JSON全局日期格式转换器如何实现的详细内容,更多请关注php中文网其它相关文章!



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


    图片新闻

    实验室药品柜的特性有哪些
    实验室药品柜是实验室家具的重要组成部分之一,主要
    小学科学实验中有哪些教学
    计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
    实验室各种仪器原理动图讲
    1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
    高中化学常见仪器及实验装
    1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
    微生物操作主要设备和器具
    今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
    浅谈通风柜使用基本常识
     众所周知,通风柜功能中最主要的就是排气功能。在

    专题文章

      CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭