i18n改为数据库维护多语言后如何根据语种动态的提示异常信息&如何在静态方法中注入非静态依赖

框架为ruoyi-vue 需求是内容国际化 静态资源已经使用接口通过json格式传给前端并赋值了 遇到的问题就是一些异常的提示信息还需要进行调整 需求就是根据前端的cookie中包含的language的值进行提示信息语言类型的判断 下面是ruoyi本身的提示信息工具类代码

public class MessageUtils {

    /**
     * 根据消息键和参数 获取消息 委托给spring messageSource
     *
     * @param code 消息键
     * @param args 参数
     * @return 获取国际化翻译值
     */
    public static String message(String code, Object... args) {
        MessageSource messageSource = SpringUtils.getBean(MessageSource.class);
        return messageSource.getMessage(code, args, LocaleContextHolder.getLocale());
    }

}

可以看出来 本来的是将i18n的静态资源实例化获取的信息

现在我们需要写一个service来从数据库中获取资源

@Service
public class LanguageService {

    @Autowired
    private LanguageMessageLoader messageLoader;


    // 这里的userthread我是从请求头中获取的language的值
    public String getMessage(String keyName) {
        return messageLoader.getMessage(keyName, UserThread.get());
    }

}
public class UserThread {
    private UserThread(){}
    //线程变量隔离
    private static final ThreadLocal<String> language = new ThreadLocal<>();

    public static void put(String str){
        language.set(str);
    }

    public static String get(){
        return language.get();
    }

    public static void remove(){
        language.remove();
    }

}

拦截器注册配置类

这里的LanguageConfig本来是ruoyi框架里的i18nConfig 因为需求用不了i18n 所以我们改造一下

@Configuration
@Slf4j
public class LanguageConfig implements WebMvcConfigurer {

    @Autowired
    private LanguageInterceptor languageInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        registry.addInterceptor(languageInterceptor)
                .addPathPatterns("/**");
    }


}

拦截器

@Component
public class LanguageInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        UserThread.put(request.getHeader("language"));
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        UserThread.remove();
    }
}
//LanguageMessage是我的语言信息实体类 属性名称需要和数据库中该表的字段一一对应

public interface LanguageMessageRepository extends CrudRepository<LanguageMessage,Long> {

    List<LanguageMessage> findAll();

    // 可以根据需要添加其他自定义的查询方法
}
// 在应用启动时加载多语言信息到内存,创建一个 MessageLoader 组件,在应用启动时从数据库加载多语言信息并存储在内存中
@Component
public class LanguageMessageLoader implements ApplicationListener<ContextRefreshedEvent> {

    @Autowired
    private LanguageMessageRepository languageMessageRepository;

    private Map<String, Map<String, String>> messages = new ConcurrentHashMap<>();

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        List<LanguageMessage> allMessages = languageMessageRepository.findAll();
        for (LanguageMessage message : allMessages) {
            messages.computeIfAbsent(message.getKeyName(), k -> new HashMap<>())
                   .put(message.getLanguageCode(), message.getMessageText());
        }
    }

    public String getMessage(String keyName, String languageCode) {
        Map<String, String> languageMessages = messages.get(keyName);
        if (languageMessages != null) {
            return languageMessages.get(languageCode);
        }
        return null;
    }
}

最后我们将messageUtils进行修改就可以了 需要注意这里的message为静态方法 我们需要通过@PostConstruct注解将非静态依赖注入到静态方法中 感兴趣可以了解下这个注解 主要是生命周期的管理  

@Component
public class MessageUtils {

    private static LanguageService languageService;

    @Autowired
    private LanguageService autowiredLanguageService;

    @PostConstruct
    public void init() {
        languageService = autowiredLanguageService;
    }


    public static String message(String code, Object... args) {
        if (languageService != null) {
            return languageService.getMessage(code);
        } else {
            // 处理 languageService 为 null 的情况
            return "LanguageService is not available";
        }
    }

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值