栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

时间出入参格式化-3:全局Timestamp出入参

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

时间出入参格式化-3:全局Timestamp出入参

时间出入参格式化-3:全局Timestamp出入参

上一篇中使用的是全局使用字符串处理时间参数。本文提供第三种处理方式:使用全局时间戳方式处理入参时间,如入参:1657096088961,这种方式同全局字符串处理方式类似,置于两者用哪种,看个人所需。

  • 优点:参数上不需要加任何注解,即可全局统一入参格式&出参格式
  • 缺点:时间报文不可读
传送链接:
  • 日期时间对象全注解方式出入参:https://www.jianshu.com/p/7049d5161c16
  • 日期时间对象全局字符串出入参:https://www.jianshu.com/p/545859a91bcd
代码实现: 定义相关常量:TimeConstants
package com.vip.tools.format.timestamp.constant;


public interface TimeConstants {
    
    String LOCAL_TIME_REGULAR = "^\d{1,2}:\d{1,2}:\d{1,2}$";
    
    String TIMESTAMP_REGULAR = "^\d{13}$";
    
    String DEFAULT_TIME_FORMAT = "HH:mm:ss";
}
转换类核心代码:TimestampToDateConverter
import com.vip.tools.format.timestamp.constant.TimeConstants;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.lang.Nullable;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.util.Date;


@Configuration
public class TimestampToDateConverter {

    @Bean(name = "localDateTimeConverter")
    public Converter localDateTimeConverter() {
        return new Converter() {
            @Override
            public LocalDateTime convert(@Nullable String source) {
                if(StringUtils.isBlank(source)){
                    return null;
                }
                if(!source.matches(TimeConstants.TIMESTAMP_REGULAR)){
                    throw new IllegalArgumentException("Invalid Time Value of Type String:" + source);
                }
                return new Date(Long.parseLong(source)).toInstant().atOffset(ZoneOffset.of("+8")).toLocalDateTime();
            }
        };
    }

    @Bean(name = "localDateConverter")
    public Converter localDateConverter() {
        return new Converter() {
            @Override
            public LocalDate convert(@Nullable String source) {
                if(StringUtils.isBlank(source)){
                    return null;
                }
                if(!source.matches(TimeConstants.TIMESTAMP_REGULAR)){
                    throw new IllegalArgumentException("Invalid Time Value of Type String:" + source);
                }
                return new Date(Long.parseLong(source)).toInstant().atOffset(ZoneOffset.of("+8")).toLocalDate();
            }
        };
    }

    @Bean(name = "localTimeConverter")
    public Converter localTimeConverter() {
        return new Converter() {
            @Override
            public LocalTime convert(@Nullable String source) {
                if(StringUtils.isBlank(source)){
                    return null;
                }
                if(!source.matches(TimeConstants.LOCAL_TIME_REGULAR)){
                    throw new IllegalArgumentException("Invalid Time Value of Type String:" + source);
                }
                return LocalTime.parse(source);
            }
        };
    }

    @Bean(name = "dateConverter")
    public Converter dateConverter() {
        return new Converter() {
            @Override
            @SneakyThrows
            public Date convert(@Nullable String source) {
                if (StringUtils.isBlank(source)) {
                    return null;
                }
                if (!source.matches(TimeConstants.TIMESTAMP_REGULAR)) {
                    throw new IllegalArgumentException("Invalid Time Value of Type String:" + source);
                }
                return new Date(Long.parseLong(source));
            }
        };
    }

}
Jackson参数转换器配置
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import com.vip.tools.format.timestamp.constant.TimeConstants;
import lombok.SneakyThrows;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Date;


public class JacksonHttpMessageConverter extends MappingJackson2HttpMessageConverter {

    public JacksonHttpMessageConverter() {
        handleDateTime();
    }

    private void handleDateTime() {
        ObjectMapper objectMapper = this.getObjectMapper();
        // Date出入参格式化
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // Java8时间格式化
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        // 出参格式化
        javaTimeModule.addSerializer(LocalDateTime.class, new MyLocalDateTimeSerializer());
        javaTimeModule.addSerializer(LocalDate.class, new MyLocalDateSerializer());
        javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(TimeConstants.DEFAULT_TIME_FORMAT)));
        // 入参格式化
        javaTimeModule.addDeserializer(LocalDateTime.class, new MyLocalDateTimeDeserializer());
        javaTimeModule.addDeserializer(LocalDate.class, new MyLocalDateDeserializer());
        javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(TimeConstants.DEFAULT_TIME_FORMAT)));
        // 把“忽略重复的模块注册”禁用,否则下面的注册(LocalDateTime)不生效
        objectMapper.disable(MapperFeature.IGNORE_DUPLICATE_MODULE_REGISTRATIONS);
        objectMapper.registerModule(javaTimeModule);
        // 然后再设置为生效,避免被其他地方覆盖
        objectMapper.enable(MapperFeature.IGNORE_DUPLICATE_MODULE_REGISTRATIONS);
        // 设置格式化内容
        this.setObjectMapper(objectMapper);
    }

    
    public static class MyLocalDateTimeSerializer extends JsonSerializer {
        @Override
        @SneakyThrows
        public void serialize(LocalDateTime localDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) {
            jsonGenerator.writeNumber(localDateTime.toInstant(ZoneOffset.ofHours(8)).toEpochMilli());
        }
    }

    
    public static class MyLocalDateSerializer extends JsonSerializer {
        @Override
        @SneakyThrows
        public void serialize(LocalDate localDate, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) {
            jsonGenerator.writeNumber(localDate.atStartOfDay(ZoneOffset.ofHours(8)).toInstant().toEpochMilli());
        }
    }

    
    public static class MyLocalDateTimeDeserializer extends JsonDeserializer {
        @Override
        @SneakyThrows
        public LocalDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) {
            return LocalDateTime.ofEpochSecond(jsonParser.getLongValue() / 1000, 0, ZoneOffset.ofHours(8));
        }
    }

    
    public static class MyLocalDateDeserializer extends JsonDeserializer {
        @Override
        @SneakyThrows
        public LocalDate deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) {
            return new Date(jsonParser.getLongValue()).toInstant().atOffset(ZoneOffset.of("+8")).toLocalDate();
        }
    }

}
WebMvcConfiguration
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;
import java.util.List;


@Configuration
@RequiredArgsConstructor
public class WebMvcConfiguration extends WebMvcConfigurationSupport {

    private final Converter localDateTimeConverter;
    private final Converter localDateConverter;
    private final Converter localTimeConverter;
    private final Converter dateConverter;

    
    @Override
    protected void addFormatters(FormatterRegistry registry) {
        registry.addConverter(localDateTimeConverter);
        registry.addConverter(localDateConverter);
        registry.addConverter(localTimeConverter);
        registry.addConverter(dateConverter);
    }

    
    @Override
    public void configureMessageConverters(List> converters) {
        super.configureMessageConverters(converters);
        JacksonHttpMessageConverter converter = new JacksonHttpMessageConverter();
        converters.add(converter);
    }

}
开始写测试代码 DTO
import lombok.Data;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;


@Data
public class TinyDTO {
    
    private Date date;

    
    private LocalDate localDate;

    
    private LocalDateTime localDateTime;

    
    private LocalTime localTime;

    
    private String name;

}
controller
import com.vip.tools.format.timestamp.dto.TinyDTO;
import com.vip.tools.normal.UuidUtils;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;


@RestController
@RequestMapping(value = "/timestamp_format")
public class TimestampDateFormatController {
    
    @PostMapping("/test")
    public TinyDTO format(@RequestParam Date date, @RequestParam LocalDate localDate, @RequestParam LocalDateTime localDateTime
            , @RequestParam LocalTime localTime, @RequestBody TinyDTO dto) {
        System.out.println(date);
        System.out.println(localDate);
        System.out.println(localDateTime);
        System.out.println(localTime);
        System.out.println(dto);
        return dto;
    }

}
测试

URL: http://localhost:9600/timestamp_format/test?date=1610595117250&localDate=1610595117250&localDateTime=1610595117250&localTime=12:00:23
Body参数:

{
	"date": 1610595117250,
	"localDate": 1610595117250,
	"localDateTime": 1610595117250,
	"localTime": "23:59:59",
	"name": "TEST"
}

控制台打印:

Thu Jan 14 11:31:57 CST 2021
2021-01-14
2021-01-14T11:31:57.250
12:00:23
TinyDTO(date=Thu Jan 14 11:31:57 CST 2021, localDate=2021-01-14, localDateTime=2021-01-14T11:31:57, localTime=23:59:59, name=TEST)

响应结果:

{
	"date": 1610595117250,
	"localDate": 1610553600000,
	"localDateTime": 1610595117000,
	"localTime": "23:59:59",
	"name": "TEST"
}

日期对象全局字符串出入参配置完成。
总结: 以上介绍了三种时间参数转换的方式,全注解方式是最不推荐的,推荐使用全局字符串转换方式,这样便于前端格式化日期格式,以及时间可阅读,全局时间戳转换方式按需使用。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1010593.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号