Skip to content

Instantly share code, notes, and snippets.

@BrightX
Created March 9, 2024 10:12
Show Gist options
  • Save BrightX/9c732d8692a8fe8e4a7789aa0e4dab78 to your computer and use it in GitHub Desktop.
Save BrightX/9c732d8692a8fe8e4a7789aa0e4dab78 to your computer and use it in GitHub Desktop.
Spring Boot 常用配置,支持多格式Date反序列化
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>5.8.26</version>
</dependency>
import cn.hutool.core.date.DateUtil;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
@Configuration
public class WebConfig implements WebMvcConfigurer {
/**
* JavaScript 中最大的安全整数 <code>2<sup>53</sup> - 1</code>
*
* @see <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER">MDN - MAX_SAFE_INTEGER</a>
*/
public static final long MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFFL;
/**
* JavaScript 中最小的安全整数 <code>-(2<sup>53</sup> - 1)</code>
*
* @see <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER">MDN - MIN_SAFE_INTEGER</a>
*/
public static final long MIN_SAFE_INTEGER = -0x1FFFFFFFFFFFFFL;
private static final DateTimeFormatter DTF = DateTimeFormatter.ofPattern("H[:m[:s[.SSS]]]");
private static final JsonSerializer<Long> SERIALIZER = new JsonSerializer<Long>() {
@Override
public void serialize(Long value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
if (value == null) {
gen.writeNull();
return;
}
// 是否是 JavaScript 安全整数
boolean isSafeInteger = MIN_SAFE_INTEGER <= value && value <= MAX_SAFE_INTEGER;
if (isSafeInteger) {
gen.writeNumber(value);
return;
}
gen.writeString(value.toString());
}
};
private static final JsonDeserializer<Date> DATE_DESERIALIZER = new JsonDeserializer<Date>() {
@Override
public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
return DateUtil.parse(p.getText());
}
};
/**
* 解决JavaScript在 json 反序列化时 long 类型缺失精度问题
*
* @return Jackson2ObjectMapperBuilderCustomizer
*/
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
return jacksonObjectMapperBuilder -> {
jacksonObjectMapperBuilder.serializerByType(Long.TYPE, SERIALIZER);
jacksonObjectMapperBuilder.serializerByType(Long.class, SERIALIZER);
jacksonObjectMapperBuilder.deserializerByType(Date.class, DATE_DESERIALIZER);
};
}
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(String.class, Date.class, DateUtil::parse);
registry.addConverter(String.class, LocalTime.class, source -> {
if ("".equals(source)) {
return null;
}
return LocalTime.parse(source, DTF);
});
registry.addConverter(String.class, LocalDate.class, source -> {
if ("".equals(source)) {
return null;
}
return LocalDate.parse(source);
});
registry.addConverter(String.class, LocalDateTime.class, source -> {
if ("".equals(source)) {
return null;
}
return DateUtil.parse(source).toLocalDateTime();
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment