Springboot国际化配置

国际化介绍

国际化(internationalization)是设计和制造容易适应不同区域要求的产品的一种方式。它要求从产品中抽离所有地域语言,国家/地区和文化相关的元素。换言之,应用程序的功能和代码设计考虑在不同地区运行的需要,其代码简化了不同本地版本的生产。开发这样的程序的过程,就称为国际化。

不知道你们在浏览网页的时候有没有发现很多网页都是支持多种语言的,比如:中文、英语等

实现国际化思路

静态语言

对于前端的静态展示信息而言我们是不是需要事先准备两套或者多套语言,当用户进行语言切换的时候,前端切换到对应的语言,但是这样会有一个弊端,假如我们现在系统只有中英文,前端也只配置了两套语言,这个时候,如果我们需要加入日语,那这个时候是不是就需要前端重新编码,重新升级?而且当语言太多的时候前端的缓存也会面临很大的压力,所以我不是很推荐这种实现方式,是否有一种可以不用升级就能实现多语言切换的问题呢?我们接着往下看。

我们将多语言这一块交给后端,由后端向前端提供语言信息,当然前端也可以配置默认的一套,防止用户第一次进入系统的时候白屏。

1.在管理平台中添加一个可以设置语言种类的功能,可以新增或者删除。
2.后端向前端提供一个语言的种类,比如现在支持多少语言的切换。
3.我们将所有的展示信息做成键值对的形式,比如中文版:code0001=首页;英文版:code0001=home,前端根据根据用户选择的语言种类获取到所有的键值对,但是这有一个前提,那就是前端需要维护一套固定的key,前端根据key就能找到对应的展示内容
4.前端向后端提供一套完整的key,后端拿着这套key值,可以随意添加任何语言种类信息。

这个时候你就会发现,前端只维护了一套默认的静态语言以及key,语言的种类、其他语言的信息都是由后端提供,假如现在需要修改某个key的值,我们可以在管理平台做实时修改,如果我现在想新增法语呢?第一步:在管理平台添加一种语言类型;第二步:我们可以使用指定格式的excel导入将数据添加到我们的数据库或者缓存中,格式可以是:key、语言。

这个时候我们发现整个系统的灵活性等到了极大的提升,不管是修改语言还是新增语种,都不需要升级前端或者后端的代码,直接在管理平台配置即可,细心的人可能已经想到了一个问题,那就是前端拉去了语言信息之后,管理平台修改了某个key的值,那什么时候会生效呢?如果你不做任何处理的话,应该是需要等到下一次拉取语言的时候了,这肯定是不行的,所以我们可以给语言增加一个版本号,当语言发生新增或者修改的时候我们同样去修改语言的版本号,后端可以通过消息推送的形式告诉前端语言已经做过修改,请更新修改过的最新语言,这里可以设计成给每个key都设置版本号,这样前端只需要拉取比当前版本号大的语言即可,不需要全部拉取。

前面讲的是前端页面的静态数据可以通过这种方式进行配置,那后端提示的信息是否也可以这样配置呢?按照刚才的逻辑来说也是可以的,这个时候就需要后端向前端提供一套后端提示语的key,后端返回前端key,前端根据后端返回的key值找到对应的提示信息,如果提示信息带参数的话,可以使用占位符的形式解决。

动态提示信息

这个时候可能你就会有疑问了?如果后端的提示消息过多会不会导致前端缓存的炸裂?有可能的,所以在这里我在介绍一种后端直接根据前端的语言类型返回指定的提示消息,不过这种相对于上面那种灵活度较低,理由:由于后端的语言配置一般都是写在配置文件的,项目启动的时候jvm会将配置文件加载到内存中,也就是说当你发现一个语言的提示消息不是很恰当想修改的时候就需要修改配置文件以及重启服务器,当然了,这两种实现方式都有着自己的长处以及弊端,你们可以结合项目的实际情况分析。

我现在来介绍一下后端通过配置文件的方式来实现国际化,实现其实很简单,我们一起来看看吧。

  1. 在resources目录下新建文件夹夹:i18n(可以随意命名,但是推荐使用i18n,internationalization国际化,共18个字母简称i18n),然后新建各种语言的配置文件:
    在这里插入图片描述

解释一下:
messages_en_US.properties:英文语言的配置。
messages_fr_FR.properties:法文语言的配置。
messages_zh_CN.properties:中文语言的配置。
messages.properties:在中、英、法配置文件中都没有找到的时候就会提示这个配置文件中的提示信息。(默认文件,非中、英文时读取)
messages_en.properties(英文)
messages_zh.properties(中文)

2.在yml文件的spring下加入下面代码:

messages:
	encoding: UTF-8
    basename: i18n/messages
    cache-second: 3600

这是我用到的内容,可以参考下格式
英文:

NotEmpty=The input cannot be null
PhoneNotEmpty=The cell phone number cannot be empty
EmailNotEmpty=The mailbox cannot be empty
CodeNotEmpty=Verification code cannot be empty
ResendCode=Please resend the verification code
PhoneRegistered=The phone number has been registered
EmailRegistered=Email registered
PhoneNotRegistered=The phone number is not registered
EmailNotRegistered=Email not registered
CodeIncorrect=Verification code is incorrect
RegisterError=Registration failed. Please try again
AuthError=Authorization failed. Please try again
OperationError=Operation failed, please try again
BindingError=Binding failed, please try again
PhoneNotExist=The cell phone number does not exist
EmailNotExist=Email does not exist
PasswordError=Password Error
AccountFrozen=The account has been frozen, please contact customer service
AccountNotAudit=The account has not been audited, please contact customer service
SendError=Failed to send. Please try again
DownloadError=Download failed, please try again
DeleteError=Delete failed, please try again
RetrieveError=Retrieve failed, please try again
UpdateError=Modification failed, please try again
OriginalPasswordError=The original password is incorrect
ArticleNotExist=There is no announcement
UploadError=Upload failed. Please try again
MessageError=Message failed, please try again
ReplyError=Reply failed, please try again
RoomEntryError=Room entry failed. Please try again
RoomExitError=Room exit failed. Please try again
CreateRoomError=Studio creation failed. Please try again

中文:

NotEmpty=输入不能为空
PhoneNotEmpty=手机号不能为空
EmailNotEmpty=邮箱不能为空
CodeNotEmpty=验证码不能为空
ResendCode=请重新发送验证码
PhoneRegistered=手机号已注册
EmailRegistered=邮箱已注册
PhoneNotRegistered=手机号未注册
EmailNotRegistered=邮箱未注册
CodeIncorrect=验证码不正确
RegisterError=注册失败,请重试
AuthError=授权失败,请重试
OperationError=操作失败,请重试
BindingError=绑定失败,请重试
PhoneNotExist=手机号不存在
EmailNotExist=邮箱不存在
PasswordError=密码错误
AccountFrozen=账号已被冻结,请联系客服
AccountNotAudit=账号未审核,请联系客服
SendError=发送失败,请重试
DownloadError=下载失败,请重试
DeleteError=删除失败,请重试
RetrieveError=密码找回失败,请重试
UpdateError=更新失败,请重试
OriginalPasswordError=原密码错误
ArticleNotExist=没有此公告
UploadError=上传失败,请重试
MessageError=留言失败,请重试
ReplyError=回复失败,请重试
RoomEntryError=房间进入失败,请重试
RoomExitError=房间退出失败,请重试
CreateRoomError=房间创建失败,请重试

3.后台公共方法:

package com.es.api.modules.common.controller;

import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.MessageSource;
import org.springframework.context.NoSuchMessageException;

import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.stereotype.Controller;

@Controller
public class I18nController {
    private static final Logger LOGGER = LoggerFactory
            .getLogger(I18nController.class);

    private MessageSource messageSource;

    /**
     * 初始化
     *
     * @return
     */
    private MessageSource initMessageSource() {
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.setBasename("i18n/messages");
        messageSource.setDefaultEncoding("UTF-8");
        messageSource.setCacheSeconds(3600);
        return messageSource;
    }

    /**
     * 设置当前的返回信息
     *
     * @param request
     * @param code
     * @return
     */
    public String getMessage(HttpServletRequest request, String code) {
        if (messageSource == null) {
            messageSource = initMessageSource();
        }
        String language = request.getHeader("language");
        //默认没有就是请求地区的语言
        Locale locale = null;
        if (language == null) {
            locale = request.getLocale();
        } else if ("en".equals(language)) {
            locale = Locale.ENGLISH;
        } else if ("zh".equals(language)) {
            locale = Locale.CHINA;
        }
        //其余的不正确的默认就是本地的语言
        else {
            locale = request.getLocale();
        }
        String result = null;
        try {
            result = messageSource.getMessage(code, null, locale);
        } catch (NoSuchMessageException e) {
            LOGGER.error("Cannot find the error message of internationalization, return the original error message.");
        }
        if (result == null) {
            return code;
        }
        return result;
    }
}

注意:传回的language是zh和en,所以我的properties文件命名直接是zh和en,这里注意下,不然错误提示是乱码

  1. 测试类
package com.test.test.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

/**
 * @author Administrator
 */
@RestController
@RequestMapping("trt")
public class TestController {


    @Autowired
    private I18nController i18n;
    @Autowired
    private HttpServletRequest request;

    @GetMapping("getError")
    public String getError() {
        String message = i18n.getMessage(request, "NotEmpty");
        return message;
    }
}

5.Postman测试

中文:
在这里插入图片描述
如果中文乱码,推荐你将中文转换成unicode,在写往配置文件中。

英文:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值