#前后端国际化多语言配置(代码片段)

MarlonBrando1998 MarlonBrando1998     2023-02-28     766

关键词:

前后端国际化多语言配置

前端(Vue ElementUI)

  • 项目前端使用Vue+Elementui
编写 i18n.js
  • 在这个js 中引入ElementUI的多语言资源,引入本地的多语言资源
// I18n
import VueI18n from 'vue-i18n'
import Vue from 'vue'
import locale from 'element-ui/lib/locale'

// 引入 elementui 的多语言
import enLocale from 'element-ui/lib/locale/lang/en'
import zhLocale from 'element-ui/lib/locale/lang/zh-CN'

// 引入自己定义的 I18n 文件
import myI18nEn from './i18n-en-US.json'
import myI18nZh from './i18n-zh-CN.json'

// 注册 vue-i18n
Vue.use(VueI18n)

// 默认中文
const lang = 'zh'
const i18n = new VueI18n(
  locale: lang,
  messages: 
    zh: Object.assign(zhLocale, myI18nZh),
    en: Object.assign(enLocale, myI18nEn)
  
)

locale.i18n((key, value) => i18n.t(key, value))
export default i18n

  • 新建i18n-en-US.json i18n-zh-CN.json文件,就是两个JSON文件
  • i18n-en-US.json

  "test": "切换语言"

  • i18n-zh-CN.json

  "test": "ChangeLanguage"

在main.js 中挂载 i18n
  • main.js
// 引入 Vue
import Vue from 'vue'

// I18n js
import i18n from './utils/i18n/I18n.js'

// 挂载 vue
new Vue(
  router,
  i18n,
  render: h => h(App)
).$mount('#app')

使用方式
<el-button size="mini" @click="changeLanguage">$t("test")</el-button>
<el-input :placeholder="$t('test')"></el-input>
切换全局的 i18n 语言
 <el-button size="mini" @click="changeLanguage">$t("test")</el-button>

// 切换语言
changeLanguage () 
    // 直接使用这个方法就可以切换
    this.$i18n.locale = this.$i18n.locale === 'en' ? 'zh' : 'en'
    // 保存到 Cookies 中方便后面发请求的时候拿到拼接到请求头中
    Cookies.set('language', this.$i18n.locale)

往后端的请求头中增加 language 参数
  • 如下封装的发送请求的js,从Cookie中拿到上面放进去的参数,当向后端请求的时候请求头部带上languange参数
// 1->common.js中引入axios
import axios from 'axios'
import QS from 'qs'
// 引入Cookie
import Cookies from 'js-cookie'

axios.defaults.timeout = 180000 // 超时时间

// 表单提交方式还是 JSON格式提交
var flag = true
// http request 拦截器
axios.interceptors.request.use(
  config => 
    // 注意使用的时候需要引入cookie方法,推荐js-cookie
    let token = Cookies.get('token')
    let language = Cookies.get('language') === undefined ? 'zh' : Cookies.get('language')
    // 登录接口不需要Token
    if (config.url.indexOf('/system/login') > 0 && config.url.indexOf('/system/loginlog') < 0) 
      return config
    
    // 如果是post请求 请求体自动加上token
    if (config.method === 'post') 
      if (token) 
        console.log(config.headers)
        config.headers = 
          'Content-Type': flag ? 'application/json' : 'application/x-www-form-urlencoded',
          // 后端生成的Token,携带Token后请求变成非简单请求
          Authorization: token,
          'language': language
        
      
     else if (config.method === 'get') 
      config.headers = 
      if (token) 
        config.headers = 
          'Content-Type': flag ? 'application/json' : 'application/x-www-form-urlencoded',
          Authorization: token,
          'language': language
        
      
    
    return config
  ,
  error => 
    // return Promise.reject(err)
    console.log(error)
  
)

// 2->对get请求传递过来的参数处理
function paramsToUrl (url, params) 
  if (!params) return url
  for (var key in params) 
    if (params[key] && params[key] !== 'undefined') 
      if (url.indexOf('?') !== -1) 
        url += '&' + '' + key + '=' + params[key] || '' + ''
       else 
        url += '?' + '' + key + '=' + params[key] || '' + ''
      
    
  
  return url


// 3->在common.js中封装公用方法-----封装请求的方法
export function requireData (url, params, type, item, paramsType) 
  // 请求参数是表单还是 json 格式
  flag = true
  if (paramsType) 
    flag = paramsType
  
  if (!url) return false
  switch (item) 
    case 'back':
      url = axios.defaults.baseM1URL + url
      break
    case 'before':
      url = axios.defaults.baseM2URL + url
      break
    case 'taskcenter':
      url = axios.defaults.baseM3URL + url
      break
    case 'core':
      url = axios.defaults.baseM4URL + url
      break
  
  if (type === 'get') 
    url = paramsToUrl(url, params)
    return new Promise((resolve, reject) => 
      axios
        .get(url, params)
        .then(res => 
          resolve(res.data)
        )
        .catch(err => 
          reject(err)
        )
    )
   else if (type === 'post') 
    // json格式请求头
    const headerJSON = 
      'Content-Type': 'application/json'
    
    // FormData格式请求头
    const headerFormData = 
      'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
    
    return new Promise((resolve, reject) => 
      axios.post(url, flag ? JSON.stringify(params) : QS.stringify(params), 
        headers: flag ? headerJSON : headerFormData
      ).then(res => 
        resolve(res.data)
      ).catch(err => 
        reject(err.data)
      )
    )
  


发送请求查看头部已经有 language 的参数

查看 Elementui 原生的多语言也生效了

后端(SpringBoot MessageSource)

使用 Spring 国际化 MessageSource
  • Spring默认集成了多语言直接使用就行了,注意配置文件要放在resource 下面不然需要配置
配置 MessageSource 可以不用配置 当多语言文件名称不是 messages开头时候必须配置
/**
  * 配置 MessageSource 其实这个可以不配置如果不配置请注意 message 多语言文件的位置
  *
  * @return
  */
@Bean
public ResourceBundleMessageSource messageSource() 
    Locale.setDefault(Locale.CHINESE);
    ResourceBundleMessageSource source = new ResourceBundleMessageSource();
    source.setBasenames("messages");
    source.setUseCodeAsDefaultMessage(true);
    source.setDefaultEncoding("UTF-8");
    logger.info(LogConstant.LOG_SUCCESS_PREFIX + "I18n配置完成");
    return source;

自定义 LocaleResolver 从请求头中获取多语言参数配置到当前域中
@Configuration
public class I18nConfig implements WebMvcConfigurer 

    private static final Logger logger = LoggerFactory.getLogger(I18nConfig.class);


    /**
     * 配置 MessageSource 其实这个可以不配置如果不配置请注意 message 多语言文件的位置
     *
     * @return
     */
    @Bean
    public ResourceBundleMessageSource messageSource() 
        Locale.setDefault(Locale.CHINESE);
        ResourceBundleMessageSource source = new ResourceBundleMessageSource();
        source.setBasenames("messages");
        source.setUseCodeAsDefaultMessage(true);
        source.setDefaultEncoding("UTF-8");
        logger.info(LogConstant.LOG_SUCCESS_PREFIX + "I18n配置完成");
        return source;
    


    /**
     * 自定义国际化组件生效注册 LocaleResolver Bean
     *
     * @return
     */
    @Bean
    public LocaleResolver localeResolver() 
        return new MyLocalResolver();
    




class MyLocalResolver implements LocaleResolver 

    /**
     * 从请求中获取多语言参数,对当前域设置多语言环境
     *
     * @param request
     * @return
     */
    @Override
    public Locale resolveLocale(HttpServletRequest request) 
        final String key = "language";
        String language = request.getHeader(key);
        Map<String, String> map = new HashMap<>(16);
        map.put("en", Locale.ENGLISH.getLanguage());
        map.put("zh", Locale.CHINESE.getLanguage());
        return new Locale(map.getOrDefault(language, "en"));
    

    @Override
    public void setLocale(HttpServletRequest request, HttpServletResponse httpServletResponse, Locale locale) 

    

注意点
// Bean 的注册 localeResolver方法名必须是这个不然注册不上
@Bean
public LocaleResolver localeResolver() 
使用
@Autowired
private MessageSource messageSource;

messageSource.getMessage("core.pageListError", null, LocaleContextHolder.getLocale()
完美完成

前后端多语言跨云部署,全链路追踪到底有多难?(代码片段)

简介: 链路追踪能覆盖全部关联IT系统,能够完整记录用户行为在系统间调用路径与状态的最佳实践方案。完整的全链路追踪可以为业务带来三大核心价值:端到端问题诊断,系统间依赖梳理,自定义标记透... 查看详情

多语言国际化(代码片段)

国际化多语言支持是现在系统通常都要具备的功能,Vue对国际化提供了很好的支持。1.安装依赖首先需要安装国际化组件,执行yarnaddvue-i18n命令,安装i18n依赖。2.添加配置在src下新建i18n目录,并创建一个index.js.importVuefrom‘vue‘im... 查看详情

django国际化(多语言)(代码片段)

1settings.pyMIDDLEWARE=(‘django.contrib.sessions.middleware.SessionMiddleware‘,#‘corsheaders.middleware.CorsMiddleware‘,‘django.middleware.locale.LocaleMiddleware‘,#中间件加上Django国际化中间件‘django.middleware 查看详情

javafx:多语言适配(代码片段)

JavaFX:多语言适配JDK国际化:ResourceBundle.html其他资源:TornadoFX编程指南,第10章,FXML和国际化、JavaFX的ResourceBundle使用创建ResourceBundle资源ResourceBundle获取资源publicclassResourceBundleUtilprivatestati 查看详情

android国际化多语言切换(代码片段)

关于App国际化,之前有讲到国际化资源、字符换、布局相关,想要了解的猛戳用力抱一下APP国际化。借着本次重构多语言想跟大家聊一下多语言切换,多语言切换对于一款国际化App来讲是重中之重,并非难事,... 查看详情

国际化intlflutter国际化多语言实践(代码片段)

目标:实现flutter国际化提示:这里参考一下几个链接例如:https://github.com/ThinkerWing/languagehttps://juejin.cn/post/6844903823119482888这篇也很详细,还有包括兼容中文的繁体简体…可以看看feat/use-Flutter-Intl该分支对应的提交... 查看详情

ios国际化(多语言)(代码片段)

一、应用程序国际化包括app名称和各种权限的提示文字。1.1创建工程,再在“PROJECT”的“Info”里面,添加所需语言。1.2从代码中分离出文本创建一个“.strings”扩展名的文件来本地化字符串,需要把这些字符串全部... 查看详情

react项目多语言国际化:react-i18next插件实现——本地数据篇(代码片段)

如何理解多语言国际化?图片中下拉部分已经清楚的说明了多语言国际化是什么了。个人理解:它就是我们在网站上可以通过切换语言类型来实现同一功能的不同语言展示效果。react-i18next介绍react-i18next是一个强大的React/ReactNativ... 查看详情

低代码平台多语言国际化(i18n)技术方案

国际化(Internationalization,简称i18n):指软件开发应当具备支持多种语言和地区的功能。也就是说能够具备切换页面显示语言的功能。i18n,其中“I”和“n”分别为首末字符,18则为中间的字符数。低代码平台/零代码平台中使用... 查看详情

yii2api接口实现国际化多语言设置(代码片段)

 1)在/config/main.php下添加如下代码:‘components‘=>[‘language‘=>‘zh-CN‘,‘i18n‘=>[‘translations‘=>[‘*‘=>[‘class‘=>‘yii\\i18n\\PhpMessageSource‘,‘basePath‘=>‘@application/messages‘,//ap 查看详情

vscode使用国际化多语言插件-i18nally&vuei18n-插件使用(代码片段)

i18nAlly&Vuei18n  用户使用vscode打开代码时安装插件后可能会自动在工作区生成这行配置"vue-i18n.i18nPaths":"src\\\\common\\\\lang",注:多语言路径"i18n-ally.localesPaths":["src/common/lang"]Vue2.x配置安装npminstallvue-i18n... 查看详情

android产品研发-->实现国际化(多语言)(代码片段)

简介最近工作中突然要求要项目进行国际化,之前没遇到过。但是也很简单呀,只需要把添加一个相应语言的的strings.xml的资源文件就好了,不是吗?这样只要切换系统语言就能切换app的文字语言了。效果图实现1.... 查看详情

vuedata中使用i18n多语言配置-切换语言不生效-解决computed(代码片段)

写在data初始化的时候拿到这些被国际化的值,并不能响应变化。官方的解决办法是,建议我们将表达式写到computed属性里,不要写到data中使用<div>$t('k.state')</div>//可以动态改变data()returndyh:this.$t('k.sta... 查看详情

前后端多语言跨云部署,全链路追踪到底有多难?(代码片段)

简介: 完整的全链路追踪可以为业务带来三大核心价值:端到端问题诊断,系统间依赖梳理,自定义标记透传。作者|涯海全链路追踪的价值链路追踪的价值在于“关联”,终端用户、后端应用、云端组件ÿ... 查看详情

angularjs国际化多语言,angular-translate教程详解,$translate.instant()为什么不生效(代码片段)

壹?引最近项目要求支持国际化多语言,由于项目用的还是angularjs,那么首当其冲的选择了angularjs封装的I18N插件angular-translate,本文主要会从三个方向展开讨论,一是基本用法,怎么用,代码是什么意思;二是问题解答,比如$tran... 查看详情

前后端多语言跨云部署,全链路追踪到底有多难?

简介:完整的全链路追踪可以为业务带来三大核心价值:端到端问题诊断,系统间依赖梳理,自定义标记透传。作者|涯海全链路追踪的价值链路追踪的价值在于“关联”,终端用户、后端应用、云端组件(... 查看详情

前后端多语言跨云部署,全链路追踪到底有多难?

简介:链路追踪能覆盖全部关联IT系统,能够完整记录用户行为在系统间调用路径与状态的最佳实践方案。完整的全链路追踪可以为业务带来三大核心价值:端到端问题诊断,系统间依赖梳理,自定义标记透传... 查看详情

前后端多语言跨云部署,全链路追踪到底有多难?

简介: 链路追踪的价值在于“关联”,终端用户、后端应用、云端组件(数据库、消息等)共同构成了链路追踪的轨迹拓扑大图。这张拓扑覆盖的范围越广,链路追踪能够发挥的价值就越大。而全链路追踪就... 查看详情