这里简单用一个详情页面开始咱们的国际化讲解 html
场景图中详情
数据是经过一个后台管理系统管理,数据经过语言隔离的方式管理,接口设计大体以下 语言管理vue
建立语种 [POST] /m/languages
更新语种 [PUT] /m/languages/{id}
查询语种 [GET] /c/languages/{id}
查询语种列表 [GET] /c/languages?$offset=偏移量&$limit=数量&$count=true&state=1
复制代码
数据管理java
建立文章 [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=数量&$count=true
复制代码
如场景图中面包屑
,好比面包屑文字首页->详情
, 像这种固定的文字不适合在后台管理由运维人员配置。用文件统一存储这些国际化的文件比较合适。这里采用SpringMVC自带的国际化解决方案。 配置ResourceBundleMessageSourcegit
@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的国际化实现github
@Bean
public CookieLocaleResolver localeResolver() {
CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver();
cookieLocaleResolver.setCookieName("lang");
return cookieLocaleResolver;
}
复制代码
SpringMVC国际化的的resolver有不少,用法也不少样,能够参考这篇博客,这里就不造轮子了(^▽^)json
国际化语言拦截器bash
@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;
}
}
复制代码
这里拦截器显示多语言路由的实现是经过改变参数来实现语言切换cookie
http://i18n.example.com?lang=en
http://i18n.example.com?lang=cn
复制代码
费些功夫经过改写这个拦截器的实现以及路由的设计,能够把国际化的路由改写成这样子框架
http://i18n.example.com/en
http://i18n.example.com/cn
复制代码
在resources中配置配置国际化语言文件运维
i18n.properties 默认
i18n_en.properties 英文
i18n_cn.properties 中文
复制代码
添加el表达式
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自带的国际化方案有一个缺陷:配置文件是内置在项目代码中的,没法剥离到后台统一管理,这样子若是新增一种语言,就必须动到项目代码。 有能力的同窗能够尝试改写ResourceBundleMessageSource,能支持读取远端的配置文件,这样就完美了。
场景图中动态推荐
部分是用js渲染出来的,其中会出现所有
等一些静态的文本。这些文本也须要国际化。我在项目中使用如今最受欢迎的js框架vue。 配合使用(vue-i18n)[http://kazupon.github.io/vue-i18n/en/started.html]进行国际化。 引入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>
复制代码
场景图中的logo
根据不一样语言也须要不一样,这样的图片须要直接其访问其图片路径,咱们约定图片的访问路径规则。
<img src="/images/logo_${lang}.svg" onerror='this.src="${ctx}/images/logo_en.svg"'/>
复制代码
国际化的文本处于各个代码文件中,手动拷贝到配置文件是一件效率至关底下且容易出错的事情。故写个自动化脚本溜起来。
随着咱国家的国力不断强盛,国际影响力不断扩大。会有更多更好的产品走向世界,国际化已经成为势不可挡的趋势。