目录
认识国际化
一、国际化开发概述
软件的国际化:软件开发时,要使它能同时应对世界不同地区和国家的访问,并针对不同地区和国家的访问,提供相应的、符合来访者阅读习惯的页面或数据。
国际化(internationalization)又称为 i18n(读法为i 18 n,据说是因为internationalization(国际化)这个单词从i到n之间有18个英文字母,i18n的名字由此而来)
二、合格的国际化软件
软件实现国际化,需具备以下两个特征:
- 对于程序中固定使用的文本元素,例如菜单栏、导航条等中使用的文本元素、或错误提示信息,状态信息等,需要根据来访者的地区和国家,选择不同语言的文本为之服务。
- 对于程序动态产生的数据,例如(日期,货币等),软件应能根据当前所在的国家或地区的文化习惯进行显示。
三、固定文本元素的国际化
对于软件中的菜单栏、导航条、错误提示信息,状态信息等这些固定不变的文本信息,可以把它们写在一个properties文件中,并根据不同的国家编写不同的properties文件。这一组properties文件称之为一个资源包。
Java实现国际化
-
yml文件引入国际化配置
spring:
messages:
basename: i18n/messages
cache-second: 3600
encoding: UTF-8
-
resources资源目录下新建文件夹i18n
文件夹下创建应语言的资源文件如图:
-
LocaleResolver简介
springMVC国际化提供了四个默认实现的类AcceptHeaderLocaleResolver,FixedLocaleResolver、CookieLocaleResolver和SessionLocaleResolver。
接下来我们简单介绍一下这四个实现类
- AcceptHeaderLocaleResolver:其实没有任何具体实现,是通过浏览器头部的语言信息来进行多语言选择。
- FixedLocaleResolver:设置固定的语言信息,这样整个系统的语言是一成不变的,用处不大。
- CookieLocaleResolver:将语言信息设置到Cookie中,这样整个系统就可以获得语言信息。
- SessionLocaleResolver:与CookieLocaleResolver类似将语言信息放到Session中,这样整个系统就可以从Session中获得语言信息。
springMVC对多语言的支持就是设置Locale的语言信息来实现的,只不过是设置了通过cookie、session等方式设置而已
-
CookieLocaleResolver 实现多语言
1、创建实例
也是最简单的方法是把CookieLocaleResolver实例注入到application中
@Bean
public LocaleResolver localeResolver() {
return new CookieLocaleResolver();
}
2、代码实现
这里可以实现对语言切换和当前语言环境的查询,这样实现完之后我们可以在其他的接口交互中不需要传语言字段,后台可以直接获取到(LocaleContextHolder.getLocale().toString())
- 切换多语言
package com.hahashujia.controller;
import com.hahashujia.basic.Result;
import com.hahashujia.config.Swagger2Config;
import com.hahashujia.config.aop.annotation.ApiType;
import com.hahashujia.sso.interfaces.LoginRequired;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.support.RequestContextUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
/**
* @author hahashujia
* @describe
* @createTime 2021-03-24 11:10
*/
@ApiType(apiTypeValue = Swagger2Config.FunctionGroup.OTHERS)
@Api(tags = "国际化切换接口")
@RestController
@RequestMapping("/api/v1/language")
@LoginRequired
public class LanguageController extends BasicController {
@ApiOperation(value = "切换语言", notes = "切换语言")
@GetMapping("/{lang}_{country}")
public Result<Locale> changeLanguage(HttpServletRequest request,
HttpServletResponse response,
@PathVariable("lang") String lang,
@PathVariable("country") String country) {
LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
localeResolver.setLocale(request, response, new Locale(lang, country));
Result result = this.getResult();
Locale locale = LocaleContextHolder.getLocale();
result.setData(locale);
return result;
}
@ApiOperation(value = "获取当前语言", notes = "获取当前语言")
@GetMapping("/current")
public Result<Locale> getCurrentLanguage() {
Result result = this.getResult();
Locale locale = LocaleContextHolder.getLocale();
result.setData(locale);
return result;
}
}
- 多语言工具类
package com.hahashujia.basic.util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;
import javax.annotation.Nullable;
import java.util.Locale;
/**
* 说明:
* 通用工具类。
* <p>
* 备注:
* 因为需要从SpringMVC上下文中获取语言信息,因此需要加入Spring Bean进行生命周期管理。
*
* @author hahashujia
*/
@Component
public class LangMessageUtils {
@Autowired
private MessageSource messageSource;
/**
* 说明:
* 获取当前的语言。
*
* @return
*/
public String getLang() {
String lang = LocaleContextHolder.getLocale().getLanguage();
return "en".equals(lang) ? "en_US" : "zh".equals(lang) ? "zh_CN" : lang;
}
/**
* 说明:
* 获取语言地区相关资源文件中的内容。
*
* @param key
* @return
*/
public String getLocaleMsg(String key, @Nullable Object[] args) {
Locale locale = LocaleContextHolder.getLocale();
return messageSource.getMessage(key, args, locale);
}
}
- 多语言工具类使用
1、注入多语言工具类
@Autowired
private LangMessageUtils langMessageUtils;
2、获取多语言信息
langMessageUtils.getLocaleMsg("FIELD_GENERAL_EMPTY_EXCEPTION", new Object[]{"userName"});
结果返回:userName此字段不允许为空
3、多语言使用
-
其他多语言实现
- 我们也可以自定义国际化配置类,通过实现LocaleResolver类,将当前用户的语言选择存储在redis中