diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/config/TranslationConfig.java b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/config/TranslationConfig.java index 5dcd0c199..d1b52fdf6 100644 --- a/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/config/TranslationConfig.java +++ b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/config/TranslationConfig.java @@ -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> list; - @Autowired - private ObjectMapper objectMapper; - @PostConstruct public void init() { Map> 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); + }; } } diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/handler/TranslationBeanSerializerModifier.java b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/handler/TranslationBeanSerializerModifier.java index 727672f25..c18fd1ee5 100644 --- a/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/handler/TranslationBeanSerializerModifier.java +++ b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/handler/TranslationBeanSerializerModifier.java @@ -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 changeProperties(SerializationConfig config, BeanDescription beanDesc, + public List changeProperties(SerializationConfig config, BeanDescription.Supplier beanDesc, List 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); } } diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/handler/TranslationHandler.java b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/handler/TranslationHandler.java index 2322cdf5d..f840524f6 100644 --- a/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/handler/TranslationHandler.java +++ b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/handler/TranslationHandler.java @@ -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 implements ContextualSerializer { +public class TranslationHandler extends ValueSerializer { /** * 全局翻译实现类映射器 @@ -40,12 +38,25 @@ public class TranslationHandler extends JsonSerializer 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 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); } }