WEB網(wǎng)站國際化的一種解決方案

場景

這里簡單用一個(gè)詳情頁面開始我們的國際化講解

國際化頁面布局.png

這個(gè)場景中,logo需要國際化,tab以及面包屑的文字需要國際化,詳情需要國際化,動(dòng)態(tài)詳情以及動(dòng)態(tài)詳情中的文字需要國際化。
經(jīng)過總結(jié),國際化數(shù)據(jù)會(huì)有四種類型

  • 后臺(tái)管理配置的動(dòng)態(tài)數(shù)據(jù)
  • 服務(wù)端渲染的靜態(tài)的文字
  • js渲染的靜態(tài)文字
  • 靜態(tài)的圖片

后臺(tái)管理配置的動(dòng)態(tài)數(shù)據(jù)

場景圖中詳情數(shù)據(jù)是通過一個(gè)后臺(tái)管理系統(tǒng)管理,數(shù)據(jù)通過語言隔離的方式管理,接口設(shè)計(jì)大致如下
語言管理

創(chuàng)建語種 [POST] /m/languages
更新語種 [PUT] /m/languages/{id}
查詢語種 [GET] /c/languages/{id}
查詢語種列表 [GET] /c/languages?$offset=偏移量&$limit=數(shù)量&$count=true&state=1

數(shù)據(jù)管理

創(chuàng)精文章 [POST] /m/languages/{language_id}/articles
更新文章 [PUT] /m/languages/articles/{article_id}
刪除文章 [DELETE] /m/languages/articles/{article_id}
查詢文章 [GET] /c/languages/articles/{article_id}
查詢文章列表 [GET]/c/languages/{language_id}/articles?$offset=偏移量&$limit=數(shù)量&$count=true

服務(wù)端渲染的靜態(tài)的文字

如場景圖中面包屑,比如面包屑文字首頁->詳情, 像這種固定的文字不適合在后臺(tái)管理由運(yùn)維人員配置。用文件統(tǒng)一存儲(chǔ)這些國際化的文件比較合適。這里采用SpringMVC自帶的國際化解決方案。
配置ResourceBundleMessageSource

@Configuration
public class I18nConfig {
    @Bean
    public ResourceBundleMessageSource messageSource() {
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        messageSource.setBasename("i18n");
        messageSource.setUseCodeAsDefaultMessage(true);
        messageSource.setDefaultEncoding("UTF-8");
        return messageSource;
    }
}

基于Cookie的國際化實(shí)現(xiàn)

 @Bean
 public CookieLocaleResolver localeResolver() {
   CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver();
   cookieLocaleResolver.setCookieName("lang");
   return cookieLocaleResolver;
 }

SpringMVC國際化的的resolver有很多,用法也很多樣,可以參考這篇博客,這里就不造輪子了()

國際化語言攔截器

@Component
public class I18nInterceptor extends HandlerInterceptorAdapter {
    public static final String DEFAULT_PARAM_NAME = "lang";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws ServletException {

        String newLocale = request.getParameter(DEFAULT_PARAM_NAME);
        if (newLocale != null) {
            LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
            if (localeResolver == null) {
                throw new IllegalStateException("No LocaleResolver found: not in a DispatcherServlet request?");
            }
            localeResolver.setLocale(request, response, StringUtils.parseLocaleString(newLocale));
        }
        // Proceed in any case.
        return true;
    }
}

這里攔截器顯示多語言路由的實(shí)現(xiàn)是通過改變參數(shù)來實(shí)現(xiàn)語言切換

http://i18n.example.com?lang=en
http://i18n.example.com?lang=cn

費(fèi)些功夫通過改寫這個(gè)攔截器的實(shí)現(xiàn)以及路由的設(shè)計(jì),可以把國際化的路由改寫成這樣子

http://i18n.example.com/en
http://i18n.example.com/cn

在resources中配置配置國際化語言文件

i18n.properties    默認(rèn)
i18n_en.properties 英文
i18n_cn.properties 中文

添加el表達(dá)式

public static String i18n(String key) {
  RequestContext requestContext = new RequestContext(SpringUtil.getRequest());
  return requestContext.getMessage(key);
}
在tld配置
<function>
    <description>國際化</description>
    <name>i18n</name>
    <function-class>com.example.utils.ElFuncUtil
    </function-class>
    <function-signature>java.lang.String i18n(java.lang.String))</function-signature>
    <example>${elf:i18n(key)}</example>
  </function>

使用

<span>${elf:i18n("詳情")}</span>

很遺憾,Spring自帶的國際化方案有一個(gè)缺陷:配置文件是內(nèi)置在項(xiàng)目代碼中的,無法剝離到后臺(tái)統(tǒng)一管理,這樣子如果新增一種語言,就必須動(dòng)到項(xiàng)目代碼。
有能力的同學(xué)可以嘗試改寫ResourceBundleMessageSource,能支持讀取遠(yuǎn)端的配置文件,這樣就完美了。

js渲染的靜態(tài)的文字

場景圖中動(dòng)態(tài)推薦部分是用js渲染出來的,其中會(huì)出現(xiàn)全部等一些靜態(tài)的文本。這些文本也需要國際化。我在項(xiàng)目中使用現(xiàn)在最受歡迎的js框架vue。
配合使用(vue-i18n)[http://kazupon.github.io/vue-i18n/en/started.html]進(jìn)行國際化。
引入vue-i18n

import Vue from 'vue'
import VueI18n from 'vue-i18n'
import messages from './message.json'
import { langCode } from '../lang'

Vue.use(VueI18n)

export default new VueI18n({
  locale: langCode,
  messages
})

message.json

"cn": {
  "全部": "全部"
},
"en": {
  "全部": "All"
}

使用

vueI18n.t('全部')
// 或者,在template模板中
<p>{{ $t("全部") }}</p>

靜態(tài)的圖片

場景圖中的logo根據(jù)不同語言也需要不同,這樣的圖片需要直接其訪問其圖片路徑,我們約定圖片的訪問路徑規(guī)則。

<img src="/images/logo_${lang}.svg" onerror='this.src="${ctx}/images/logo_en.svg"'/>

抽取配置的自動(dòng)化腳本

國際化的文本處于各個(gè)代碼文件中,手動(dòng)拷貝到配置文件是一件效率相當(dāng)?shù)紫虑胰菀壮鲥e(cuò)的事情。故寫個(gè)自動(dòng)化腳本溜起來。
抽取國際化文本成json文件的自動(dòng)化腳本實(shí)現(xiàn)
抽取國際化文本成properties文件的自動(dòng)化腳本實(shí)現(xiàn)
把properties中的文件轉(zhuǎn)移到xlsx文件中的自動(dòng)化腳本實(shí)現(xiàn)

結(jié)語

隨著咱國家的國力不斷強(qiáng)盛,國際影響力不斷擴(kuò)大。會(huì)有更多更好的產(chǎn)品走向世界,國際化已經(jīng)成為勢不可擋的趨勢。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容