no message
All checks were successful
Gitea Actions Build / Build (push) Successful in 1m0s

This commit is contained in:
Armamem0t 2025-09-11 19:32:51 +08:00
parent 2c29e40e47
commit baa5aafe23
Signed by: minglipro
GPG Key ID: 5F355A77B22AA93B
9 changed files with 289 additions and 188 deletions

View File

@ -22,4 +22,4 @@
JDKVERSIONS=1.8
GROUPSID=com.mingliqiye.utils
ARTIFACTID=mingli-utils
VERSIONS=3.1.5
VERSIONS=3.2.3

View File

@ -0,0 +1,70 @@
package com.mingliqiye.utils.json.converters;
import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.reader.ObjectReader;
import com.alibaba.fastjson2.writer.ObjectWriter;
import java.lang.reflect.Type;
public class FastjsonJsonStringConverterAdapter<
T extends JsonStringConverter<TT>,
TT
> {
private final JsonStringConverter<TT> jsonStringConverter;
public FastjsonJsonStringConverterAdapter(T jsonStringConverter) {
this.jsonStringConverter = jsonStringConverter;
}
public static <
T extends JsonStringConverter<TT>,
TT
> FastjsonJsonStringConverterAdapter<T, TT> of(T t) {
return new FastjsonJsonStringConverterAdapter<>(t);
}
/**
* 获取FastJson对象写入器
*
* @return FastJson的ObjectWriter实例
*/
public ObjectWriter<T> getFastJsonObjectWriter() {
return (
JSONWriter writer,
Object object,
Object fieldName,
Type fieldType,
long features
) -> {
// 如果对象为null则写入null
if (object == null) {
writer.writeNull();
return;
}
writer.writeString(jsonStringConverter.convert((TT) object));
};
}
/**
* 获取FastJson对象读取器
*
* @return FastJson的ObjectReader实例
*/
public ObjectReader<TT> getFastJsonObjectReader() {
return (
JSONReader reader,
Type fieldType,
Object fieldName,
long features
) -> {
String value = reader.readString();
return jsonStringConverter.deConvert(value);
};
}
}

View File

@ -0,0 +1,50 @@
package com.mingliqiye.utils.json.converters;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
public class GsonJsonStringConverterAdapter<
T extends JsonStringConverter<TT>,
TT
> {
private final JsonStringConverter<TT> jsonStringConverter;
public GsonJsonStringConverterAdapter(T jsonStringConverter) {
this.jsonStringConverter = jsonStringConverter;
}
public static <
T extends JsonStringConverter<TT>,
TT
> GsonJsonStringConverterAdapter<T, TT> of(T t) {
return new GsonJsonStringConverterAdapter<>(t);
}
/**
* 获取Gson类型适配器
*
* @return Gson的TypeAdapter实例
*/
public TypeAdapter<TT> getGsonTypeAdapter() {
return new TypeAdapter<TT>() {
@Override
public void write(JsonWriter out, TT value) throws IOException {
if (value == null) {
out.nullValue();
return;
}
out.value(jsonStringConverter.convert(value));
}
@Override
public TT read(JsonReader in) throws IOException {
String value = in.nextString();
return jsonStringConverter.deConvert(value);
}
};
}
}

View File

@ -0,0 +1,91 @@
package com.mingliqiye.utils.json.converters;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.io.IOException;
/**
* JSON转换器的适配器
* @param <T> JSON转换器
* @param <TT> JSON转换器的泛型
* @author MingLiPro
*/
public class JacksonJsonStringConverterAdapter<
T extends JsonStringConverter<TT>,
TT
> {
private final JsonStringConverter<TT> jsonStringConverter;
private JacksonJsonStringConverterAdapter(T jsonStringConverter) {
this.jsonStringConverter = jsonStringConverter;
}
/**
*
* @param t JSON转换器实例
* @return JSON转换器的适配器
* @param <T> JSON转换器
* @param <TT> JSON转换器的泛型
*/
public static <
T extends JsonStringConverter<TT>,
TT
> JacksonJsonStringConverterAdapter<T, TT> of(T t) {
return new JacksonJsonStringConverterAdapter<>(t);
}
/**
* 获取Jackson反序列化器
*
* @return Jackson的JsonDeserializer实例
*/
public JsonDeserializer<TT> getJacksonJsonDeserializer() {
return new JsonDeserializer<TT>() {
@Override
public TT deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException {
if (p.isNaN()) return null;
return jsonStringConverter.deConvert(p.getValueAsString());
}
};
}
/**
* 获取Jackson序列化器
*
* @return Jackson的JsonSerializer实例
*/
public JsonSerializer<TT> getJacksonJsonSerializer() {
return new JsonSerializer<TT>() {
@Override
public void serialize(
TT value,
JsonGenerator gen,
SerializerProvider serializers
) throws IOException {
if (value == null) {
gen.writeNull();
return;
}
gen.writeString(jsonStringConverter.convert(value));
}
};
}
/**
*
* 获取 Jackson 的格式化模块
*
* @return 格式化模块
*/
public Module getJacksonModule() {
Class<TT> tClass = jsonStringConverter.getTClass();
SimpleModule m = new SimpleModule(tClass.getSimpleName());
m.addSerializer(tClass, getJacksonJsonSerializer());
m.addDeserializer(tClass, getJacksonJsonDeserializer());
return m;
}
}

View File

@ -1,19 +1,5 @@
package com.mingliqiye.utils.json.converters;
import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.reader.ObjectReader;
import com.alibaba.fastjson2.writer.ObjectWriter;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.lang.reflect.Type;
/**
* JSON转换器接口提供对象与字符串之间的相互转换功能并支持多种JSON库
*
@ -40,118 +26,35 @@ public abstract class JsonStringConverter<T> {
abstract T deConvert(String string);
/**
* 获取Jackson反序列化器
*
* @return Jackson的JsonDeserializer实例
* 获取 Fastjson 的适配器
* @return 适配器实例
*/
public JsonDeserializer<T> getJacksonJsonDeserializer() {
return new JsonDeserializer<T>() {
@Override
public T deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException {
// 如果是NaN则返回null
if (p.isNaN()) return null;
return deConvert(p.getValueAsString());
}
};
public FastjsonJsonStringConverterAdapter<
JsonStringConverter<T>,
T
> getFastjsonJsonStringConverterAdapter() {
return FastjsonJsonStringConverterAdapter.of(this);
}
/**
* 获取Jackson序列化器
*
* @return Jackson的JsonSerializer实例
* 获取 Gson 的适配器
* @return 适配器实例
*/
public JsonSerializer<T> getJacksonJsonSerializer() {
return new JsonSerializer<T>() {
@Override
public void serialize(
T value,
JsonGenerator gen,
SerializerProvider serializers
) throws IOException {
// 如果值为null则写入null
if (value == null) {
gen.writeNull();
return;
}
gen.writeString(convert(value));
}
};
}
public Module getJacksonModule() {
Class<T> tClass = getTClass();
SimpleModule m = new SimpleModule(tClass.getSimpleName());
m.addSerializer(tClass, getJacksonJsonSerializer());
m.addDeserializer(tClass, getJacksonJsonDeserializer());
return m;
public GsonJsonStringConverterAdapter<
JsonStringConverter<T>,
T
> getGsonJsonStringConverterAdapter() {
return GsonJsonStringConverterAdapter.of(this);
}
/**
* 获取Gson类型适配器
*
* @return Gson的TypeAdapter实例
* 获取 Jackson 的适配器
* @return 适配器实例
*/
public TypeAdapter<T> getGsonTypeAdapter() {
return new TypeAdapter<T>() {
@Override
public void write(JsonWriter out, T value) throws IOException {
// 如果值为null则写入null值
if (value == null) {
out.nullValue();
return;
}
out.value(convert(value));
}
@Override
public T read(JsonReader in) throws IOException {
String value = in.nextString();
return deConvert(value);
}
};
}
/**
* FastJson 支持
*/
/**
* 获取FastJson对象写入器
*
* @return FastJson的ObjectWriter实例
*/
public ObjectWriter<T> getFastJsonObjectWriter() {
return (
JSONWriter writer,
Object object,
Object fieldName,
Type fieldType,
long features
) -> {
// 如果对象为null则写入null
if (object == null) {
writer.writeNull();
return;
}
writer.writeString(convert((T) object));
};
}
/**
* 获取FastJson对象读取器
*
* @return FastJson的ObjectReader实例
*/
public ObjectReader<T> getFastJsonObjectReader() {
return (
JSONReader reader,
Type fieldType,
Object fieldName,
long features
) -> {
String value = reader.readString();
return deConvert(value);
};
public JacksonJsonStringConverterAdapter<
JsonStringConverter<T>,
T
> getJacksonJsonStringConverterAdapter() {
return JacksonJsonStringConverterAdapter.of(this);
}
}

View File

@ -2,6 +2,8 @@ package com.mingliqiye.utils.springboot.autoconfigure;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.mingliqiye.utils.json.GsonJsonApi;
import com.mingliqiye.utils.json.JsonApi;
import com.mingliqiye.utils.json.converters.DateTimeJsonConverter;
import com.mingliqiye.utils.json.converters.JsonStringConverter;
import com.mingliqiye.utils.json.converters.UUIDJsonStringConverter;
@ -13,14 +15,15 @@ import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.gson.GsonBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
@ConditionalOnClass(Gson.class)
@AutoConfiguration
@AutoConfigureAfter(
name = {
"org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration",
"com.mingliqiye.utils.springboot.autoconfigure.JacksonAutoConfiguration",
}
)
public class GsonAutoConfiguration {
@ -34,25 +37,37 @@ public class GsonAutoConfiguration {
new DateTimeJsonConverter();
JsonStringConverter<UUID> uuidJsonStringConverter =
new UUIDJsonStringConverter();
return gsonBuilder
.registerTypeAdapter(
uuidJsonStringConverter.getTClass(),
uuidJsonStringConverter.getGsonTypeAdapter()
)
.registerTypeAdapter(
dateTimeJsonConverter.getTClass(),
dateTimeJsonConverter.getGsonTypeAdapter()
);
}
@Bean
@Primary
@ConditionalOnMissingBean
public GsonBuilder gsonBuilder() {
try {
return addTypeAdapter(new GsonBuilder());
return gsonBuilder
.registerTypeAdapter(
uuidJsonStringConverter.getTClass(),
dateTimeJsonConverter
.getGsonJsonStringConverterAdapter()
.getGsonTypeAdapter()
)
.registerTypeAdapter(
dateTimeJsonConverter.getTClass(),
dateTimeJsonConverter
.getGsonJsonStringConverterAdapter()
.getGsonTypeAdapter()
);
} finally {
log.info("MingliUtils GsonBuilder TypeAdapter add");
}
}
@Bean
public GsonBuilderCustomizer mingliGsonCustomizer() {
return GsonAutoConfiguration::addTypeAdapter;
}
@Bean
@ConditionalOnMissingBean
public JsonApi jsonApi(Gson gson) {
log.info(
"MingliUtils-JsonApiAutoConfiguration: GsonJsonApi bean is created."
);
return new GsonJsonApi(gson);
}
}

View File

@ -1,6 +1,8 @@
package com.mingliqiye.utils.springboot.autoconfigure;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mingliqiye.utils.json.JacksonJsonApi;
import com.mingliqiye.utils.json.JsonApi;
import com.mingliqiye.utils.json.converters.DateTimeJsonConverter;
import com.mingliqiye.utils.json.converters.UUIDJsonStringConverter;
import org.slf4j.Logger;
@ -8,6 +10,9 @@ import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
@ConditionalOnClass(ObjectMapper.class)
@AutoConfiguration
@ -29,7 +34,25 @@ public class JacksonAutoConfiguration {
public static ObjectMapper addModules(ObjectMapper objectMapper) {
return objectMapper
.registerModule(new UUIDJsonStringConverter().getJacksonModule())
.registerModule(new DateTimeJsonConverter().getJacksonModule());
.registerModule(
new DateTimeJsonConverter()
.getJacksonJsonStringConverterAdapter()
.getJacksonModule()
)
.registerModule(
new UUIDJsonStringConverter()
.getJacksonJsonStringConverterAdapter()
.getJacksonModule()
);
}
@Bean
@Primary
@ConditionalOnMissingBean
public JsonApi jsonApi(ObjectMapper objectMapper) {
log.info(
"MingliUtils-JsonApiAutoConfiguration: JacksonJsonApi bean is created."
);
return new JacksonJsonApi(objectMapper);
}
}

View File

@ -1,50 +0,0 @@
package com.mingliqiye.utils.springboot.autoconfigure;
import com.mingliqiye.utils.json.JsonApi;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
@AutoConfiguration
@AutoConfigureAfter(
name = {
"com.mingliqiye.utils.springboot.autoconfigure.GsonAutoConfiguration",
"com.mingliqiye.utils.springboot.autoconfigure.JacksonAutoConfiguration",
}
)
public class JsonApiAutoConfiguration {
private static final Logger log = LoggerFactory.getLogger(
"MingliUtils-JsonApiAutoConfiguration"
);
@Bean
@Primary
@ConditionalOnMissingBean
@ConditionalOnClass(
name = { "com.fasterxml.jackson.databind.ObjectMapper" }
)
public JsonApi jacksonJsonApi(
com.fasterxml.jackson.databind.ObjectMapper objectMapper
) {
log.info(
"MingliUtils-JsonApiAutoConfiguration: JacksonJsonApi bean is created."
);
return new com.mingliqiye.utils.json.JacksonJsonApi(objectMapper);
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnClass(name = { "com.google.gson.Gson" })
public JsonApi gsonJsonApi(com.google.gson.Gson gson) {
log.info(
"MingliUtils-JsonApiAutoConfiguration: GsonJsonApi bean is created."
);
return new com.mingliqiye.utils.json.GsonJsonApi(gson);
}
}

View File

@ -23,4 +23,3 @@
com.mingliqiye.utils.springboot.autoconfigure.AutoConfiguration
com.mingliqiye.utils.springboot.autoconfigure.JacksonAutoConfiguration
com.mingliqiye.utils.springboot.autoconfigure.GsonAutoConfiguration
com.mingliqiye.utils.springboot.autoconfigure.JsonApiAutoConfiguration