国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

springcloud微服務國際化

這篇具有很好參考價值的文章主要介紹了springcloud微服務國際化。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

一、初探

單體應用完成國際化還是比較簡單的,可以看下面的示例代碼。
引入必要的依賴

<!-- SpringBoot Web -->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- Validator -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

<!-- i18n -->
<dependency>
   <groupId>org.webjars.bower</groupId>
   <artifactId>jquery-i18n-properties</artifactId>
   <version>1.2.7</version>
</dependency>

創(chuàng)建一個攔截器

import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.support.RequestContextUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LocaleInterceptor extends LocaleChangeInterceptor {
    private static final String LOCALE = "Accept-Language";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        String newLocale = request.getHeader(LOCALE);
        if (newLocale != null) {
            LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
            if (localeResolver == null) {
                throw new IllegalStateException("No LocaleResolver found: not in a DispatcherServlet request?");
            }
            try {
                localeResolver.setLocale(request, response, parseLocaleValue(newLocale));
            } catch (IllegalArgumentException ignore) {
            }
        }
        return true;
    }
}

創(chuàng)建一個配置類

import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;

import java.nio.charset.StandardCharsets;
import java.util.Locale;

@Configuration
public class LocaleConfig implements WebMvcConfigurer{
    /**
     *	默認解析器 其中l(wèi)ocale表示默認語言,當請求中未包含語種信息,則設置默認語種
     *	當前默認為簡體中文,zh_CN
     */
    @Bean
    public SessionLocaleResolver localeResolver() {
        SessionLocaleResolver localeResolver = new SessionLocaleResolver();
        localeResolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);
        return localeResolver;
    }

    /**
     *  默認攔截器
     *  攔截請求,獲取請求頭中包含的語種信息并重新注冊語種信息
     */
    @Bean
    public WebMvcConfigurer localeInterceptor() {
        return new WebMvcConfigurer() {
            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                registry.addInterceptor(new LocaleInterceptor());
            }
        };
    }

    @Bean
    public LocalValidatorFactoryBean localValidatorFactoryBean() {
        LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
        // 設置消息源
        bean.setValidationMessageSource(resourceBundleMessageSource());
        return bean;
    }

    @Bean
    public MessageSource resourceBundleMessageSource() {
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        messageSource.setDefaultEncoding(StandardCharsets.UTF_8.toString());
        // 多語言文件地址
        messageSource.addBasenames("i18n/message");
        return messageSource;
    }

    @Bean
    public MethodValidationPostProcessor validationPostProcessor() {
        MethodValidationPostProcessor processor = new MethodValidationPostProcessor();
        processor.setValidator(localValidatorFactoryBean().getValidator());
        return processor;
    }

    @Override
    public Validator getValidator() {
        return localValidatorFactoryBean();
    }
}

然后在resource下創(chuàng)建i18n目錄,選中右鍵 New =>Resource Bundle
springcloud微服務國際化
填入base name,選擇Project locales,再Add All,確定即可。
springcloud微服務國際化
打開配置文件,填寫對應的中英文數(shù)據
springcloud微服務國際化
配置一下application.yml

spring:
  messages:
    basename: i18n.message
    cache-duration: 3600
    encoding: UTF-8

這樣基本上就好了,使用也很簡單,看下圖
springcloud微服務國際化

二、深入

對于微服務來講,每個模塊單獨配置國際化還是很繁瑣的事情。所以一般是將國際化存入數(shù)據庫進行統(tǒng)一管理。而本地緩存使用Redis替換,從而更新國際化之后,相應的模塊能同步。

先把原來的LocaleConfigLocaleInterceptor抽離到公共服務,同時增加一個自定義MessageSource

import com.xxx.common.core.domain.RpcResult;
import com.xxx.common.redis.service.RedisService;
import com.xxx.system.api.RemoteLocaleMessageService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.support.AbstractMessageSource;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.annotation.PostConstruct;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.Map;

@Slf4j
@Component("messageSource")
public class CustomMessageSource extends AbstractMessageSource {
    public static final String REDIS_LOCALE_MESSAGE_KEY = "i18n_message";

    @Value("${spring.application.name}")
    private String appName;

	/**
	* 這里使用的是dubbo,也可以用open feign
	* 需要引入dubbo的依賴包 spring-cloud-starter-dubbo
	*/
    @DubboReference(version = "1.0.0")
    private RemoteLocaleMessageService i18nMessageMapper;

    @Autowired
    private RedisService redisService;

    @PostConstruct
    public void init() {
        log.info("init i18n message...");
        redisService.deleteObject(REDIS_LOCALE_MESSAGE_KEY + ":" + appName);
        this.reload();
    }

    /**
     * 重新加載消息到該類的Map緩存中
     */
    public Map<String, Map<String, String>> reload() {
        Map<String, Map<String, String>> localeMsgMap = redisService.getCacheMap(REDIS_LOCALE_MESSAGE_KEY + ":" + appName);
        if (localeMsgMap == null || localeMsgMap.isEmpty()) {
            // 加載所有的國際化資源
            localeMsgMap = this.loadAllMessageResources();
            // 緩存到redis
            if (localeMsgMap != null && !localeMsgMap.isEmpty()) {
                redisService.setCacheMap(REDIS_LOCALE_MESSAGE_KEY + ":" + appName, localeMsgMap);
            }
        }
        return localeMsgMap;
    }

    @Override
    protected MessageFormat resolveCode(String code, Locale locale) {
        String msg = this.getSourceFromCacheMap(code, locale);
        return new MessageFormat(msg, locale);
    }

    @Override
    protected String resolveCodeWithoutArguments(String code, Locale locale) {
        return this.getSourceFromCacheMap(code, locale);
    }

    /**
     * 加載所有的國際化消息資源
     *
     * @return
     */
    private Map<String, Map<String, String>> loadAllMessageResources() {
        // 從數(shù)據庫中查詢所有的國際化資源
        RpcResult<Map<String, Map<String, String>>> rpcResult = i18nMessageMapper.getAllLocaleMessage(appName);
        return rpcResult.getCode() == 200 ? rpcResult.getData() : null;
    }

    /**
     * 緩存Map中加載國際化資源
     *
     * @param code
     * @param locale
     * @return
     */
    private String getSourceFromCacheMap(String code, Locale locale) {
        // 判斷如果沒有值則會去重新加載數(shù)據
        Map<String, Map<String, String>> localeMsgMap = this.reload();
        String language = ObjectUtils.isEmpty(locale) ? LocaleContextHolder.getLocale().getLanguage() : locale.getLanguage();
        // 獲取緩存中對應語言的所有數(shù)據項
        Map<String, String> propMap = localeMsgMap.get(language);
        if (!ObjectUtils.isEmpty(propMap) && propMap.containsKey(code)) {
            // 如果對應語言中能匹配到數(shù)據項,那么直接返回
            return propMap.get(code);
        }
        // 如果找不到國際化消息,就直接返回code
        return code;
    }
}

并對LocaleConfig進行改造

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.validation.MessageInterpolatorFactory;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;

import java.nio.charset.StandardCharsets;
import java.util.Locale;

@Configuration
public class LocaleConfig implements WebMvcConfigurer {

     @Autowired
     private CustomMessageSource customMessageSource;

    /**
     *	默認解析器 其中l(wèi)ocale表示默認語言,當請求中未包含語種信息,則設置默認語種
     *	當前默認為SIMPLIFIED_CHINESE,zh_CN
     */
    @Bean
    public SessionLocaleResolver localeResolver() {
        SessionLocaleResolver localeResolver = new SessionLocaleResolver();
        localeResolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);
        return localeResolver;
    }

    /**
     *  默認攔截器
     *  攔截請求,獲取請求頭中包含的語種信息并重新注冊語種信息
     */
    @Bean
    public WebMvcConfigurer localeInterceptor() {
        return new WebMvcConfigurer() {
            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                registry.addInterceptor(new LocaleInterceptor());
            }
        };
    }

    @Bean
    public LocalValidatorFactoryBean localValidatorFactoryBean() {
        LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
        MessageInterpolatorFactory interpolatorFactory = new MessageInterpolatorFactory();
        bean.setMessageInterpolator(interpolatorFactory.getObject());
        // 設置消息源
        bean.setValidationMessageSource(resourceBundleMessageSource());
        return bean;
    }

    @Bean
    public MessageSource resourceBundleMessageSource() {
        return customMessageSource;
    }

    @Bean
    public MethodValidationPostProcessor validationPostProcessor() {
        MethodValidationPostProcessor processor = new MethodValidationPostProcessor();
        processor.setValidator(localValidatorFactoryBean().getValidator());
        return processor;
    }

    @Override
    public Validator getValidator() {
        return localValidatorFactoryBean();
    }
}

在需要的模塊中引入即可。

Dubbo provider的實現(xiàn)

import com.xxx.common.core.domain.RpcResult;
import com.xxx.system.api.RemoteLocaleMessageService;
import com.xxx.system.entity.SysLocaleMessage;
import com.xxx.system.service.ISysLocaleMessageService;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@DubboService(version = "1.0.0")
public class DubboLocaleMessageService implements RemoteLocaleMessageService {
    @Autowired
    private ISysLocaleMessageService localeMessageService;

    private final String COMMON_CONFIG = "common";

	// 這里不能返回List,因為無法序列化,會導致Dubbo異常,所以使用Map
    @Override
    public RpcResult<Map<String, Map<String, String>>> getAllLocaleMessage(String module) {
        // 每個module對應的配置
        SysLocaleMessage localeMessage = new SysLocaleMessage();
        localeMessage.setModule(module);
        List<SysLocaleMessage> list = localeMessageService.queryByParam(localeMessage);
        if (list == null) {
            list = new ArrayList<>();
        }
        // 公共配置
        localeMessage = new SysLocaleMessage();
        localeMessage.setModule(COMMON_CONFIG);
        list.addAll(localeMessageService.queryByParam(localeMessage));
        if (CollectionUtils.isEmpty(list)) {
            return RpcResult.fail("no data!");
        }

        Map<String, Map<String, String>> localeMsgMap = list.stream().collect(Collectors.groupingBy(
                // 根據國家地區(qū)分組
                SysLocaleMessage::getLocale,
                // 收集為Map,key為code,msg為信息
                Collectors.toMap(SysLocaleMessage::getCode, SysLocaleMessage::getMsg)
        ));
        return RpcResult.success(localeMsgMap);
    }
}

將國際化的增刪改查功能集成到系統(tǒng)管理,就可以通過數(shù)據庫進行管理了。
springcloud微服務國際化
對國際化進行增刪改后,需要對Redis緩存進行更新

/**
 * 清理Redis所有前綴匹配的緩存
 */
private void clearCache() {
    Collection<String> keys = redisService.keys(CustomMessageSource.REDIS_LOCALE_MESSAGE_KEY + "*");
    keys.stream().forEach(key -> {
        redisService.deleteObject(key);
    });
}

/**
 * 按key清理Redis緩存
 */
private void clearCache(String key) {
    redisService.deleteObject(CustomMessageSource.REDIS_LOCALE_MESSAGE_KEY + ":" + key);
}

之前創(chuàng)建的resouce/i18n目錄則可以刪除。使用也是和單體應用一樣的。
springcloud微服務國際化文章來源地址http://www.zghlxwxcb.cn/news/detail-405812.html

到了這里,關于springcloud微服務國際化的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • SpringBoot——國際化

    SpringBoot——國際化

    優(yōu)質博文:IT-BLOG-CN 【1】編寫國際化配置文件; 【2】使用 ResourceBundleMessageSource 管理國際化資源文件; 【3】在頁面使用 ftp:message 取出國際化內容; 【1】創(chuàng)建 i18n 目錄,并創(chuàng)建 login.properties 國際化默認配置文件,同時創(chuàng)建 login_zh_CN.properties 系統(tǒng)就會自動識別到是配置國際化

    2024年02月05日
    瀏覽(18)
  • hyperf 十四 國際化

    官方網址:Hyperf 文件結構: ????????/storage/languages/en/messages.php ????????/storage/languages/zh_CH/messages.php 創(chuàng)建文件 /config/autoload/translation.php。 多語言的調用從注入開始,即HyperfTranslationTranslator::__construct(TranslatorLoaderInterface $loader, string $locale)方法。根據配置文件Translato

    2024年02月11日
    瀏覽(24)
  • 微信小程序國際化

    微信小程序國際化

    參考文件: 國際化(微信小程序+TS 微信小程序國際化 https://github.com/wechat-miniprogram/miniprogram-i18n 注意:一定要注意項目目錄結構,新建文件夾miniprogram,并把前面新建的文件移到這個目錄中 在NEW-FAN-CLOCK1 中安裝根目錄依賴 在NEW-FAN-CLOCK1 / minprogram 中安裝依賴 1、初始化倉庫: 一

    2023年04月26日
    瀏覽(19)
  • SpringBoot復習:(36)國際化

    SpringBoot復習:(36)國際化

    一、Resources目錄下建立一個目錄(比如international)來存儲資源文件 message.properties 空的,但不能沒有 message_zh_CN.properties message_en_us.properties 二、自動配置類MessageSourceAutoConfiguration 常量MESSAGE_SOURCE_BEAN_NAME為messageSource,也就是有這個名字的bean,則自動配置失效。 因為有@Conditional(R

    2024年02月13日
    瀏覽(29)
  • vue2+element-ui使用vue-i18n進行國際化的多語言/國際化

    vue2+element-ui使用vue-i18n進行國際化的多語言/國際化

    注意:vue2.0要用8版本的,使用9版本的會報錯 在src目錄下,創(chuàng)建新的文件夾,命名為i18n zh.js en.js index.js main.js 使用方式一 效果圖 使用方式二 效果圖 使用方式三,在 效果圖 ` 注意:這種方式存在更新this.$i18n.locale的值時無法自動切換的問題,需要刷新頁面才能切換語言。解

    2024年02月07日
    瀏覽(24)
  • Android國際化各國語言簡寫

    2024年02月16日
    瀏覽(24)
  • 第七十一回:國際化設置

    我們在上一章回中介紹了Card Widget相關的內容,本章回中將介紹 國際化設置 .閑話休提,讓我們一起Talk Flutter吧。 我們在這里說的國際化設置是指在App設置相關操作,這樣可以讓不同國家的用戶使用App時呈現(xiàn)不同的語言??傊?,就是通過相關的操作,讓App支持多個國家的語言

    2024年02月11日
    瀏覽(101)
  • Spring Boot實現(xiàn)國際化

    config controller 在Thymeleaf模板中引用國際化消息:

    2024年01月23日
    瀏覽(21)
  • Flutter GetX 之 國際化

    今天給大家介紹一下 GetX 的國際化功能,在日常開發(fā)過程中,我們經常會使用到國際化功能,需要們的應用支持 國際化,例如我們需要支持 簡體、繁體、英文等等。 上幾篇文章介紹了GetX的 路由管理 和 狀態(tài)管理,看到大家的點贊和收藏,還是很開心的,說明這兩篇文章給大

    2024年01月19日
    瀏覽(33)
  • 如何優(yōu)雅的實現(xiàn)前端國際化?

    如何優(yōu)雅的實現(xiàn)前端國際化?

    JavaScript 中每個常見問題都有許多成熟的解決方案。當然,國際化 (i18n) 也不例外,有很多成熟的 JavaScript i18n 庫可供選擇,下面就來分享一些熱門的前端國際化庫! i18next 是一個用 JavaScript 編寫的全面的國際化框架,提供標準的 i18n 功能,包括復數(shù)、上下文、插值、格式等。

    2024年01月23日
    瀏覽(39)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包