update 翻译模块升级jackson3

This commit is contained in:
疯狂的狮子Li
2026-03-19 10:43:43 +08:00
parent da21874a67
commit 2edbaf9269
3 changed files with 62 additions and 32 deletions

View File

@@ -1,14 +1,16 @@
package org.dromara.common.translation.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.translation.annotation.TranslationType;
import org.dromara.common.translation.core.TranslationInterface;
import org.dromara.common.translation.core.handler.TranslationBeanSerializerModifier;
import org.dromara.common.translation.core.handler.TranslationHandler;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.jackson.autoconfigure.JsonMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import tools.jackson.databind.ser.SerializerFactory;
import java.util.HashMap;
import java.util.List;
@@ -26,9 +28,6 @@ public class TranslationConfig {
@Autowired
private List<TranslationInterface<?>> list;
@Autowired
private ObjectMapper objectMapper;
@PostConstruct
public void init() {
Map<String, TranslationInterface<?>> map = new HashMap<>(list.size());
@@ -41,10 +40,15 @@ public class TranslationConfig {
}
}
TranslationHandler.TRANSLATION_MAPPER.putAll(map);
// 设置 Bean 序列化修改器
objectMapper.setSerializerFactory(
objectMapper.getSerializerFactory()
.withSerializerModifier(new TranslationBeanSerializerModifier()));
}
@Bean
public JsonMapperBuilderCustomizer translationInitCustomizer() {
return builder -> {
SerializerFactory serializerFactory = builder.serializerFactory();
serializerFactory = serializerFactory.withSerializerModifier(new TranslationBeanSerializerModifier());
builder.serializerFactory(serializerFactory);
};
}
}

View File

@@ -1,9 +1,9 @@
package org.dromara.common.translation.core.handler;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
import tools.jackson.databind.BeanDescription;
import tools.jackson.databind.SerializationConfig;
import tools.jackson.databind.ser.BeanPropertyWriter;
import tools.jackson.databind.ser.ValueSerializerModifier;
import java.util.List;
@@ -12,10 +12,18 @@ import java.util.List;
*
* @author Lion Li
*/
public class TranslationBeanSerializerModifier extends BeanSerializerModifier {
public class TranslationBeanSerializerModifier extends ValueSerializerModifier {
/**
* 为翻译字段补充空值序列化器,确保字段值为 {@code null} 时仍能走翻译处理链。
*
* @param config 当前序列化配置
* @param beanDesc Bean 描述提供者
* @param beanProperties 当前 Bean 的属性写入器列表
* @return 调整后的属性写入器列表
*/
@Override
public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc,
public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription.Supplier beanDesc,
List<BeanPropertyWriter> beanProperties) {
for (BeanPropertyWriter writer : beanProperties) {
// 如果序列化器为 TranslationHandler 的话 将 Null 值也交给他处理
@@ -23,7 +31,7 @@ public class TranslationBeanSerializerModifier extends BeanSerializerModifier {
writer.assignNullSerializer(serializer);
}
}
return beanProperties;
return super.changeProperties(config, beanDesc, beanProperties);
}
}

View File

@@ -1,19 +1,17 @@
package org.dromara.common.translation.core.handler;
import cn.hutool.core.util.ObjectUtil;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.core.utils.reflect.ReflectUtils;
import org.dromara.common.translation.annotation.Translation;
import org.dromara.common.translation.core.TranslationInterface;
import lombok.extern.slf4j.Slf4j;
import tools.jackson.core.JacksonException;
import tools.jackson.core.JsonGenerator;
import tools.jackson.databind.BeanProperty;
import tools.jackson.databind.SerializationContext;
import tools.jackson.databind.ValueSerializer;
import java.io.IOException;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
@@ -24,7 +22,7 @@ import java.util.concurrent.ConcurrentHashMap;
* @author Lion Li
*/
@Slf4j
public class TranslationHandler extends JsonSerializer<Object> implements ContextualSerializer {
public class TranslationHandler extends ValueSerializer<Object> {
/**
* 全局翻译实现类映射器
@@ -40,12 +38,25 @@ public class TranslationHandler extends JsonSerializer<Object> implements Contex
this.translation = null;
}
/**
* 创建绑定指定翻译注解的序列化处理器。
*
* @param translation 当前字段上声明的翻译注解
*/
public TranslationHandler(Translation translation) {
this.translation = translation;
}
/**
* 将原始字段值翻译为展示值并写回序列化结果。
*
* @param value 原始字段值
* @param gen Json 输出器
* @param ctxt 序列化上下文
* @throws JacksonException Json 序列化异常
*/
@Override
public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
public void serialize(Object value, JsonGenerator gen, SerializationContext ctxt) throws JacksonException {
TranslationInterface<?> trans = TRANSLATION_MAPPER.get(translation.type());
if (ObjectUtil.isNotNull(trans)) {
// 如果映射字段不为空 则取映射字段的值
@@ -59,23 +70,30 @@ public class TranslationHandler extends JsonSerializer<Object> implements Contex
}
try {
Object result = trans.translation(value, translation.other());
gen.writeObject(result);
gen.writePOJO(result);
} catch (Exception e) {
log.error("翻译处理异常type: {}, value: {}", translation.type(), value, e);
// 出现异常时输出原始值而不是中断序列化
gen.writeObject(value);
gen.writePOJO(value);
}
} else {
gen.writeObject(value);
gen.writePOJO(value);
}
}
/**
* 按字段上的 {@link Translation} 注解创建上下文相关的翻译序列化器。
*
* @param ctxt 序列化上下文
* @param property 当前序列化属性
* @return 存在翻译注解时返回新的翻译处理器,否则沿用默认序列化器
*/
@Override
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
public ValueSerializer<?> createContextual(SerializationContext ctxt, BeanProperty property) {
Translation translation = property.getAnnotation(Translation.class);
if (Objects.nonNull(translation)) {
return new TranslationHandler(translation);
}
return prov.findValueSerializer(property.getType(), property);
return super.createContextual(ctxt, property);
}
}