因为有时候承接一些国外项目,项目需要支持国际化。国际化包括页面静态文字的国际化,接口中返回的信息的国际化,JS脚本里内容的国际化。
一、配置国际化语言
在openjweb-core工程中增加默认国际化语言配置类:
package org.openjweb.core.config;
import java.util.Locale;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
//配置国际化语言
@Configuration
public class LocaleConfig {
/**
* 默认解析器 其中locale表示默认语言 LocaleResolver 用于设置当前会话的默认的国际化语言。
*/
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver localeResolver = new SessionLocaleResolver();
localeResolver.setDefaultLocale(Locale.CHINA);//指定默认语言,,英文可指定Locale.US
return localeResolver;
}
}
二、增加配置类,指定国际化参数
国际化参数指在URL中通过?后面的国际化参数来选择语言。除了浏览器根据操作系统选择默认语种外,也可以手工指定。例如?lang=zh_CN 表示读取国际化文件messages_zh_CN.properties。下面增加一个WebMvcConfig配置类,实现WebMvcConfigurer,这个类后面还可以增加全局跨域控制等(以后再介绍)。
package org.openjweb.core.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
//默认拦截器 其中lang表示切换语言的参数名 LocaleChangeInterceptor 指定切换国际化语言的参数名。
// 例如?lang=zh_CN 表示读取国际化文件messages_zh_CN.properties。
//System.out.println("增加国际化拦截器...........");
LocaleChangeInterceptor localeInterceptor = new LocaleChangeInterceptor();
localeInterceptor.setParamName("lang");// 指定设置国际化的参数
registry.addInterceptor(localeInterceptor);
}
}
三、按语种、key值获取国际化内容的工具类
开发一个根据语种、key值获取国际化内容的工具类MessageUtils(在openjweb-common的路径下):
package org.openjweb.common.util;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;
@Component
public class MessageUtils {
private static MessageSource messageSource;
public MessageUtils(MessageSource messageSource) {
MessageUtils.messageSource = messageSource;
}
/**
* 获取单个国际化翻译值
*/
public static String get(String msgKey) {
try {
return messageSource.getMessage(msgKey, null, LocaleContextHolder.getLocale());
} catch (Exception e) {
return msgKey;
}
}
}
四、创建国际化配置文件
在openjweb-sys的application-dev.yml里指定国际化文件的相对路径为static/i18n.messages,并在resources下创建static\i18n目录。application-dev.xml这样配置:
spring:
messages:
basename: static/i18n.message
注意static前不加/ ,static/i18n.messages ,是指src/main/resources/static/i18n下面以messages开头的国际化文件,千万不要写成static/i18n/messages ,网上很多例子写成了static/i18n/messages ,导致无法实现国际化!也可以写成 static.i18n.messages 。下面在resources/static/i18n目录下创建三个文件(分别是中文简体、英文、中文繁体):
messages_en_US.properties文件内容:
user.title=User Login
user.welcome=Welcome
user.username=Username
user.password=Password
user.login=Sign In
messages_zh_CN.properties (保存后可能自动转unicode码,不方便维护),所以需要把项目的properties字符集设置为UTF-8:
文件内容:
user.title=用户登陆
user.welcome=欢迎
user.username=登陆用户
user.password=登陆密码
user.login=登陆
再建一个中文繁体的messages_zh_TW.properties:
user.title=用戶登陸
user.welcome=歡迎
user.username=登陸用戶
user.password=登陸密碼
user.login=登陸
切记还要增加一个默认的messages.peoperties,否则多语种解析不生效,这个文件复制messages_zh_CN即可,哪个是默认语种就复制哪个。
五、创建静态测试页
现在做一个静态测试页,在src/main/resources/templates/建一个userlist.html文件(项目以前有这个测试页了,现在国际化):
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>hello</title>
<meta htp-equiv="Content-Type" content="text/html;charset=UTF-8"/>
</head>
<body>
<table>
<tr>
<td>用户名</td>
<!--非国际化-->
<td>登录账号</td>
<!--国际化-->
<td th:text="#{user.title}">登录账号 </td>
</tr>
<tr th:each="user:${users}">
<td th:text="${user.realName}"></td>
<td th:text="${user.loginId}"></td>
</tr>
</body>
</table>
</html>
上面的代码中,使用的是thymeleaf模板,国际化成功后,会将登录账号改为国际化定义文件里user.title 设置的值。现在我们开发一个控制层的类,指定视图为这个userlist.html,之前的示例介绍了这个控制层类,现在再贴下代码:
package org.openjweb.sys.controller;
import org.openjweb.sys.entity.CommUser;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.ArrayList;
import java.util.List;
@Controller
@RequestMapping("/demo/tmpl/")
public class TemplateController {
//http://localhost:8001/demo/tmpl/queryUser
@RequestMapping(value = "queryUser")
public String list(Model model) {
List<CommUser> userList = new ArrayList<>();
CommUser user = new CommUser();
user.setLoginId("admin");
user.setRealName("阿宝");
userList.add(user);
model.addAttribute("users", userList);
return "userlist";//不知道是否区分大小写
}
//http://localhost:8001/demo/tmpl/queryUser2
@RequestMapping(value = "queryUser2")
public ModelAndView list2() {
List<CommUser> userList = new ArrayList<>();
CommUser user = new CommUser();
user.setLoginId("admin");
user.setRealName("阿宝");
userList.add(user);
ModelAndView model = new ModelAndView();
model.addObject("users",userList);
model.setViewName("userlist");//指定视图
return model;//这个前端没有解析出来
}
}
启动SpringBoot,分别按下面的链接访问:
http://localhost:8001/demo/tmpl/queryUser
http://localhost:8001/demo/tmpl/queryUser?lang=zh_CN 简体中文
http://localhost:8001/demo/tmpl/queryUser?lang=en_US 美式英文
http://localhost:8001/demo/tmpl/queryUser?lang=zh_TW 繁体中文
上面的模板引擎使用的thymeleaf,那么如果模板引擎使用的beetle,是否也支持国际化标签呢?网上找到这个例子,可以参考下:Spring boot+beetl+i18n国际化处理的方法 - 编程语言 - 亿速云国际化(internationalization)是设计和制造容易适应不同区域要求的产品的一种方式。它要求从产品中抽离所有地域语言,国家/地区和文化相关的元素。换言之,�...https://www.yisu.com/jc/202561.html
现在我们看下演示的效果:
那么如果是VUE前后端分离的模式如何做国际化呢?这个以后再研究,这种情况可以考虑VUE页面所有的文字标签都要从后台获取对应语种的标签。
六、JS文件国际化
为什么要考虑JS文件的国际化?因为js文件的一些提示信息可能不需要直接从后台获取动态信息,所以需要考虑JS文件的国际化。如果使用jquery,国际化需要引入下面的依赖(在openjweb-core的pom.xml中添加):
<dependency>
<!--webjars版本定位器 用于省略版本号-->
<groupId>org.webjars</groupId>
<artifactId>webjars-locator-core</artifactId>
</dependency>
<dependency>
<!--jQuery前端依赖-->
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.6.0</version>
</dependency>
<dependency>
<!--jQuery国际化插件-->
<groupId>org.webjars.bower</groupId>
<artifactId>jquery-i18n-properties</artifactId>
<version>1.2.7</version>
</dependency>
然后在上面的WebMvcConfig.java中增加一个自定义的映射,这样就不用再单独写Controller了,仅用于测试JS多语:
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/testduoyu").setViewName("testduoyu");//不能命名testlocale 可能locale有冲突
}
然后在openjweb-sys的resources/templates下创建一个testduoyu.html文件:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title th:text="#{user.title}">用户登陆</title>
<!-- 演示如何定位js的路径 -->
<script th:src="@{/webjars/jquery/3.6.0/jquery.min.js}"></script>
<script th:src="@{/webjars/jquery-i18n-properties/1.2.7/jquery.i18n.properties.min.js}"></script>
<script th:inline="javascript">
//获取应用路径
var ROOT = [[${#servletContext.contextPath}]];//自定义映射影响取不到值?
//获取默认语言
var LANG_COUNTRY = [[${#locale.language+'_'+#locale.country}]];
console.log("ROOT IS:");
console.log(ROOT);
console.log(LANG_COUNTRY);//get zh_CN
//alert("ROOT:"+ROOT);
//alert("LANG_COUNTRY:"+LANG_COUNTRY);//正常获取
//初始化i18n插件
$.i18n.properties({
path: ROOT + 'i18n/',//这里表示访问路径--不要加static ,这个是相对路径
name: 'messages',//文件名开头
language: LANG_COUNTRY,//文件名语言 例如en_US
mode: 'both'//默认值
});
//初始化i18n函数
function i18n(msgKey) {
try {
return $.i18n.prop(msgKey);
} catch (e) {
return msgKey;
}
}
//获取国际化翻译值
console.log(i18n('user.title'));//通过js的i18读取多语文字
alert(i18n('user.title'));
console.log(i18n('User Login'));
</script>
</head>
<body>
<div class="logo_box">
<select id="locale">
<option value="zh_CN">中文简体</option>
<option value="zh_TW">中文繁体</option>
<option value="en_US">English</option>
</select>
<h3 th:text="#{user.welcome}">欢迎登陆</h3>
<form>
<div class="input_outer">
<span class="u_user"></span>
<input id="username" name="username" class="text" type="text" th:placeholder="#{user.username}">
</div>
<div class="input_outer">
<span class="us_uer"></span>
<input id="password" name="password" class="text" type="password" th:placeholder="#{user.password}">
</div>
<div class="mb2">
<a class="act-but submit" th:text="#{user.login}">登录</a>
</div>
</form>
</div>
<script th:inline="javascript">
//选中语言
$("#locale").find('option[value="' + LANG_COUNTRY + '"]').attr('selected', true);
//切换语言
$("#locale").change(function () {
var url=ROOT + '/testduoyu?lang=' + $("#locale").val();
location.href=url;
//alert(url)
$.get(url, function () {
location.reload();
});
});
</script>
</body>
</html>
注意<script th:src="@{/webjars/jquery/3.6.0/jquery.min.js}"></script>路径的写法,这个是打开本机Maven下载的webjars,在.m2\repository\org\webjars\jquery\3.6.0有个jquery-3.6.0.jar,打开这个,对应里面的路径:
i18对应js的写法:<script th:src="@{/webjars/jquery-i18n-properties/1.2.7/jquery.i18n.properties.min.js}"></script>
获取应用路径: var ROOT = [[${#servletContext.contextPath}]];
thymeleaf取上下文路径,如果application.properties配置server.servlet.context-path=/comm,则ROOT为/comm,访问路径则需要加上/comm如: http://localhost:8001/comm/....
var LANG_COUNTRY = [[${#locale.language+'_'+#locale.country}]]; 计算当前选择语种及国家,返回格式示例zh_CN
使用i18n取不同语种内容:
在测试JS国际化之前,因为需要js需要访问webjars路径和i18n下面的messages*.properties文件,所以WebSecurityConfig文件的地址白名单里需要增加/webjars/**和/i18n/**,见下面的代码:
.antMatchers("/login.html", "/img/**","/demo/**","/webjars/**", "/testduoyu","/i18n/**").permitAll()
testduoyu.html中,alert(i18n('user.title')); 演示了js读取国际化文件user.title的值。
接下来演示JS的多语种展示:
http://localhost:8001/demo/testduoyu?lang=zh_CN
http://localhost:8001/demo/testduoyu?lang=en_US
http://localhost:8001/demo/testduoyu?lang=zh_TW
注意:测试的时候请package打成jar包启动(java -jar openjweb-sys-0.0.1-SNAPSHOT.jar),目前发现不打包直接在IDEA里运行应用显示乱码。
可以看出,选择不同的语种,alert窗口会显示对应语种的提示信息。
以上是在HTML页面和JS中国际化的示例。后面会介绍接口返回JSON的全局国际化处理。
本文源码可从github上下载:
https://github.com/openjweb/cloud/tree/masterhttps://github.com/openjweb/cloud/tree/master
标签:27,IntelliJ,--,springframework,国际化,user,import,i18n,org From: https://blog.csdn.net/baozhengw/article/details/144254829