Merge branch 'master-jdk17' of https://gitee.com/zhijiantianya/yudao-cloud
commit
88687d2719
|
@ -1,10 +1,10 @@
|
||||||
package cn.iocoder.yudao.framework.jackson.config;
|
package cn.iocoder.yudao.framework.jackson.config;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
|
||||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.json.databind.NumberSerializer;
|
import cn.iocoder.yudao.framework.common.util.json.databind.NumberSerializer;
|
||||||
import cn.iocoder.yudao.framework.common.util.json.databind.TimestampLocalDateTimeDeserializer;
|
import cn.iocoder.yudao.framework.common.util.json.databind.TimestampLocalDateTimeDeserializer;
|
||||||
import cn.iocoder.yudao.framework.common.util.json.databind.TimestampLocalDateTimeSerializer;
|
import cn.iocoder.yudao.framework.common.util.json.databind.TimestampLocalDateTimeSerializer;
|
||||||
|
import com.fasterxml.jackson.databind.Module;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
|
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
|
||||||
|
@ -13,39 +13,65 @@ import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
|
||||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
|
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
|
||||||
|
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@AutoConfiguration
|
@AutoConfiguration(after = JacksonAutoConfiguration.class)
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class YudaoJacksonAutoConfiguration {
|
public class YudaoJacksonAutoConfiguration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从 Builder 源头定制(关键:使用 *ByType,避免 handledType 要求)
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public Jackson2ObjectMapperBuilderCustomizer ldtEpochMillisCustomizer() {
|
||||||
|
return builder -> builder
|
||||||
|
// Long -> Number
|
||||||
|
.serializerByType(Long.class, NumberSerializer.INSTANCE)
|
||||||
|
.serializerByType(Long.TYPE, NumberSerializer.INSTANCE)
|
||||||
|
// LocalDate / LocalTime
|
||||||
|
.serializerByType(LocalDate.class, LocalDateSerializer.INSTANCE)
|
||||||
|
.deserializerByType(LocalDate.class, LocalDateDeserializer.INSTANCE)
|
||||||
|
.serializerByType(LocalTime.class, LocalTimeSerializer.INSTANCE)
|
||||||
|
.deserializerByType(LocalTime.class, LocalTimeDeserializer.INSTANCE)
|
||||||
|
// LocalDateTime < - > EpochMillis
|
||||||
|
.serializerByType(LocalDateTime.class, TimestampLocalDateTimeSerializer.INSTANCE)
|
||||||
|
.deserializerByType(LocalDateTime.class, TimestampLocalDateTimeDeserializer.INSTANCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 以 Bean 形式暴露 Module(Boot 会自动注册到所有 ObjectMapper)
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public Module timestampSupportModuleBean() {
|
||||||
|
SimpleModule m = new SimpleModule("TimestampSupportModule");
|
||||||
|
// Long -> Number,避免前端精度丢失
|
||||||
|
m.addSerializer(Long.class, NumberSerializer.INSTANCE);
|
||||||
|
m.addSerializer(Long.TYPE, NumberSerializer.INSTANCE);
|
||||||
|
// LocalDate / LocalTime
|
||||||
|
m.addSerializer(LocalDate.class, LocalDateSerializer.INSTANCE);
|
||||||
|
m.addDeserializer(LocalDate.class, LocalDateDeserializer.INSTANCE);
|
||||||
|
m.addSerializer(LocalTime.class, LocalTimeSerializer.INSTANCE);
|
||||||
|
m.addDeserializer(LocalTime.class, LocalTimeDeserializer.INSTANCE);
|
||||||
|
// LocalDateTime < - > EpochMillis
|
||||||
|
m.addSerializer(LocalDateTime.class, TimestampLocalDateTimeSerializer.INSTANCE);
|
||||||
|
m.addDeserializer(LocalDateTime.class, TimestampLocalDateTimeDeserializer.INSTANCE);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化全局 JsonUtils,直接使用主 ObjectMapper
|
||||||
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@SuppressWarnings("InstantiationOfUtilityClass")
|
@SuppressWarnings("InstantiationOfUtilityClass")
|
||||||
public JsonUtils jsonUtils(List<ObjectMapper> objectMappers) {
|
public JsonUtils jsonUtils(ObjectMapper objectMapper) {
|
||||||
// 1.1 创建 SimpleModule 对象
|
JsonUtils.init(objectMapper);
|
||||||
SimpleModule simpleModule = new SimpleModule();
|
log.debug("[init][初始化 JsonUtils 成功]");
|
||||||
simpleModule
|
|
||||||
// 新增 Long 类型序列化规则,数值超过 2^53-1,在 JS 会出现精度丢失问题,因此 Long 自动序列化为字符串类型
|
|
||||||
.addSerializer(Long.class, NumberSerializer.INSTANCE)
|
|
||||||
.addSerializer(Long.TYPE, NumberSerializer.INSTANCE)
|
|
||||||
.addSerializer(LocalDate.class, LocalDateSerializer.INSTANCE)
|
|
||||||
.addDeserializer(LocalDate.class, LocalDateDeserializer.INSTANCE)
|
|
||||||
.addSerializer(LocalTime.class, LocalTimeSerializer.INSTANCE)
|
|
||||||
.addDeserializer(LocalTime.class, LocalTimeDeserializer.INSTANCE)
|
|
||||||
// 新增 LocalDateTime 序列化、反序列化规则,使用 Long 时间戳
|
|
||||||
.addSerializer(LocalDateTime.class, TimestampLocalDateTimeSerializer.INSTANCE)
|
|
||||||
.addDeserializer(LocalDateTime.class, TimestampLocalDateTimeDeserializer.INSTANCE);
|
|
||||||
// 1.2 注册到 objectMapper
|
|
||||||
objectMappers.forEach(objectMapper -> objectMapper.registerModule(simpleModule));
|
|
||||||
|
|
||||||
// 2. 设置 objectMapper 到 JsonUtils
|
|
||||||
JsonUtils.init(CollUtil.getFirst(objectMappers));
|
|
||||||
log.info("[init][初始化 JsonUtils 成功]");
|
|
||||||
return new JsonUtils();
|
return new JsonUtils();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
package cn.iocoder.yudao.gateway.jackson;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.json.databind.NumberSerializer;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.json.databind.TimestampLocalDateTimeDeserializer;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.json.databind.TimestampLocalDateTimeSerializer;
|
||||||
|
import com.fasterxml.jackson.databind.Module;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
|
||||||
|
import org.springframework.boot.web.codec.CodecCustomizer;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.http.codec.json.Jackson2JsonDecoder;
|
||||||
|
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalTime;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@Slf4j
|
||||||
|
public class GatewayJacksonAutoConfiguration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从 Builder 源头定制(关键:使用 *ByType,避免 handledType 要求)
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public Jackson2ObjectMapperBuilderCustomizer ldtEpochMillisCustomizer() {
|
||||||
|
return builder -> builder
|
||||||
|
// Long -> Number
|
||||||
|
.serializerByType(Long.class, NumberSerializer.INSTANCE)
|
||||||
|
.serializerByType(Long.TYPE, NumberSerializer.INSTANCE)
|
||||||
|
// LocalDate / LocalTime
|
||||||
|
.serializerByType(LocalDate.class, LocalDateSerializer.INSTANCE)
|
||||||
|
.deserializerByType(LocalDate.class, LocalDateDeserializer.INSTANCE)
|
||||||
|
.serializerByType(LocalTime.class, LocalTimeSerializer.INSTANCE)
|
||||||
|
.deserializerByType(LocalTime.class, LocalTimeDeserializer.INSTANCE)
|
||||||
|
// LocalDateTime < - > EpochMillis
|
||||||
|
.serializerByType(LocalDateTime.class, TimestampLocalDateTimeSerializer.INSTANCE)
|
||||||
|
.deserializerByType(LocalDateTime.class, TimestampLocalDateTimeDeserializer.INSTANCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 以 Bean 形式暴露 Module(Boot 会自动注册到所有 ObjectMapper)
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public Module timestampSupportModuleBean() {
|
||||||
|
SimpleModule m = new SimpleModule("TimestampSupportModule");
|
||||||
|
// Long -> Number
|
||||||
|
m.addSerializer(Long.class, NumberSerializer.INSTANCE);
|
||||||
|
m.addSerializer(Long.TYPE, NumberSerializer.INSTANCE);
|
||||||
|
// LocalDate / LocalTime
|
||||||
|
m.addSerializer(LocalDate.class, LocalDateSerializer.INSTANCE);
|
||||||
|
m.addDeserializer(LocalDate.class, LocalDateDeserializer.INSTANCE);
|
||||||
|
m.addSerializer(LocalTime.class, LocalTimeSerializer.INSTANCE);
|
||||||
|
m.addDeserializer(LocalTime.class, LocalTimeDeserializer.INSTANCE);
|
||||||
|
// LocalDateTime < - > EpochMillis
|
||||||
|
m.addSerializer(LocalDateTime.class, TimestampLocalDateTimeSerializer.INSTANCE);
|
||||||
|
m.addDeserializer(LocalDateTime.class, TimestampLocalDateTimeDeserializer.INSTANCE);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化全局 JsonUtils,直接使用主 ObjectMapper
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@SuppressWarnings("InstantiationOfUtilityClass")
|
||||||
|
public JsonUtils jsonUtils(ObjectMapper objectMapper) {
|
||||||
|
JsonUtils.init(objectMapper);
|
||||||
|
log.debug("[init][初始化 JsonUtils 成功]");
|
||||||
|
return new JsonUtils();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WebFlux 场景:强制默认编解码器使用同一个 ObjectMapper
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public CodecCustomizer unifyJackson(ObjectMapper om) {
|
||||||
|
return configurer -> {
|
||||||
|
Jackson2JsonDecoder decoder = new Jackson2JsonDecoder(om);
|
||||||
|
Jackson2JsonEncoder encoder = new Jackson2JsonEncoder(om);
|
||||||
|
configurer.defaultCodecs().jackson2JsonDecoder(decoder);
|
||||||
|
configurer.defaultCodecs().jackson2JsonEncoder(encoder);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,51 +0,0 @@
|
||||||
package cn.iocoder.yudao.gateway.jackson;
|
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
|
||||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
|
||||||
import cn.iocoder.yudao.framework.common.util.json.databind.NumberSerializer;
|
|
||||||
import cn.iocoder.yudao.framework.common.util.json.databind.TimestampLocalDateTimeDeserializer;
|
|
||||||
import cn.iocoder.yudao.framework.common.util.json.databind.TimestampLocalDateTimeSerializer;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
|
||||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
|
|
||||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
|
|
||||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
|
|
||||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.LocalTime;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@Slf4j
|
|
||||||
public class JacksonAutoConfiguration {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public JsonUtils jsonUtils(List<ObjectMapper> objectMappers) {
|
|
||||||
// 1.1 创建 SimpleModule 对象
|
|
||||||
SimpleModule simpleModule = new SimpleModule();
|
|
||||||
simpleModule
|
|
||||||
// 新增 Long 类型序列化规则,数值超过 2^53-1,在 JS 会出现精度丢失问题,因此 Long 自动序列化为字符串类型
|
|
||||||
.addSerializer(Long.class, NumberSerializer.INSTANCE)
|
|
||||||
.addSerializer(Long.TYPE, NumberSerializer.INSTANCE)
|
|
||||||
.addSerializer(LocalDate.class, LocalDateSerializer.INSTANCE)
|
|
||||||
.addDeserializer(LocalDate.class, LocalDateDeserializer.INSTANCE)
|
|
||||||
.addSerializer(LocalTime.class, LocalTimeSerializer.INSTANCE)
|
|
||||||
.addDeserializer(LocalTime.class, LocalTimeDeserializer.INSTANCE)
|
|
||||||
// 新增 LocalDateTime 序列化、反序列化规则,使用 Long 时间戳
|
|
||||||
.addSerializer(LocalDateTime.class, TimestampLocalDateTimeSerializer.INSTANCE)
|
|
||||||
.addDeserializer(LocalDateTime.class, TimestampLocalDateTimeDeserializer.INSTANCE);
|
|
||||||
// 1.2 注册到 objectMapper
|
|
||||||
objectMappers.forEach(objectMapper -> objectMapper.registerModule(simpleModule));
|
|
||||||
|
|
||||||
// 2. 设置 objectMapper 到 JsonUtils
|
|
||||||
JsonUtils.init(CollUtil.getFirst(objectMappers));
|
|
||||||
log.info("[init][初始化 JsonUtils 成功]");
|
|
||||||
return new JsonUtils();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue