• Spring Boot 国际化 i18n


    Spring Cloud 微服务系列文章,点击上方合集↑

    1. 简介

    什么是国际化?国际化就是让您的应用系统适配不同的国家和语言,在中国就是中文,在中国台湾就自动切换为繁体中文,在美国就切换成英语。

    i18n是国际化internationalization这个单词的缩写,取了首字母i和结尾字母n,中间有18个字母,相同的命名方式有k8s

    2. Spring Boot 国际化

    2.1 application.properties

    server.port=8960
    spring.application.name=i18n-demo
    # 国际化配置文件目录
    spring.messages.basename=i18n/messages
    
    • 1
    • 2
    • 3
    • 4
    • i18n是存放目录
    • messages是文件前缀

    2.2 国际化配置文件

    resources目录下创建i18n文件夹,然后在i18n目录下创建如下文件:

    • messages.properties默认语言
    • messages_en_US.properties英文语言
    • messages_zh_CN.properties简体中文
    • messages_zh_TW.properties繁体中文
    2.2.1 messages.properties
    opr_success=Operation successful
    opr_fail=Operation failed
    msg_welcome=welcome,{0}!
    
    • 1
    • 2
    • 3
    • 可以通过{0}传递参数。
    2.2.2 messages_en_US.properties
    # English
    opr_success=Operation successful
    opr_fail=Operation failed
    msg_welcome=welcome,{0}!
    
    • 1
    • 2
    • 3
    • 4
    2.2.3 messages_zh_CN.properties
    # 简体中文
    opr_success=操作成功
    opr_fail=操作失败
    msg_welcome=欢迎,{0}!
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    2.2.4 messages_zh_TW.properties
    # 繁體中文
    opr_success=操作成功
    opr_fail=操作失敗
    msg_welcome=歡迎,{0}!
    
    • 1
    • 2
    • 3
    • 4

    2.3 简单使用

    MessageSourcegetMessage方法,传入不同的Locale就调用不同的语言。如messageSource.getMessage("opr_success", null, Locale.SIMPLIFIED_CHINESE);

    并且可以创建一个数组如new String[]{name}来传递参数,对应配置中的{0}

    @RestController
    @RequestMapping("i18n")
    public class I18nController {
        @Autowired
        private MessageSource messageSource;
    
        @GetMapping("success")
        public String success() {
            return messageSource.getMessage("opr_success", null, Locale.SIMPLIFIED_CHINESE);
        }
    
        @GetMapping("fail")
        public String fail() {
            return messageSource.getMessage("opr_fail", null, Locale.US);
        }
    
        @GetMapping("test")
        public String test(@RequestParam String name) {
            return messageSource.getMessage("msg_welcome", new String[]{name}, Locale.TRADITIONAL_CHINESE);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    3. 优雅的使用

    3.1 LocaleInterceptor

    定义一个拦截器:前端通过参数lang传入语言类型,如zh_CN,根据传入的参数生成对应的Locale对象,并通过LocaleContextHolder.setLocale(locale)Locale对象放入上下文对象中。

    public class LocaleInterceptor implements HandlerInterceptor {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
            String lang = request.getParameter("lang");
            Locale locale = Locale.SIMPLIFIED_CHINESE;
    
            if (lang != null && !lang.trim().isEmpty()) {
                String[] langParts = lang.split("_");
                if (langParts.length == 2) {
                    locale = new Locale(langParts[0], langParts[1]);
                }
            }
    
            LocaleContextHolder.setLocale(locale);
    
            return true;
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
            LocaleContextHolder.resetLocaleContext();
        }
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    3.2 WebConfig

    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new LocaleInterceptor());
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3.3 I18nUtils

    封装I18nUtils类,提供getMessage方法获取语言文字,通过LocaleContextHolder.getLocale()从上下文中获取Locale对象。

    @Component
    public class I18nUtils {
        private static MessageSource messageSource;
    
        @Autowired
        public I18nUtils(MessageSource messageSource) {
            I18nUtils.messageSource = messageSource;
        }
    
        public static String getMessage(String key) {
            return getMessage(key, null);
        }
    
        public static String getMessage(String key, Object[] args) {
            Locale locale = LocaleContextHolder.getLocale();
            return messageSource.getMessage(key, args, locale);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3.4 I18nController

    @RestController
    @RequestMapping("i18n")
    public class I18nController {
        @GetMapping("welcome")
        public String welcome(@RequestParam String name) {
            return I18nUtils.getMessage("msg_welcome", new String[]{name});
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    4. 接口测试

    4.1 中文

    http://localhost:8960/i18n/success

    操作成功
    
    • 1

    4.2 英文

    http://localhost:8960/i18n/fail

    Operation failed
    
    • 1

    4.3 传入参数

    http://localhost:8960/i18n/test?name=%E5%BC%A0%E4%B8%89

    歡迎,张三!
    
    • 1

    4.4 lang=zh_TW指定语言

    http://localhost:8960/i18n/welcome?name=%E5%BC%A0%E4%B8%89&lang=zh_TW

    歡迎,张三!
    
    • 1

    4.5 默认的语言

    http://localhost:8960/i18n/welcome?name=%E5%BC%A0%E4%B8%89

    欢迎,张三!
    
    • 1

    5. 总结

    建议在系统早期考虑国际化,即使目前只面向中文用户。尽早进行国际化设计能够避免后续需要适配其它语言(如英语、繁体中文)时带来的麻烦。您可以先实现一个默认的中文版本,这样不会给后续工作增加太多负担。记住,提前考虑国际化能够增加系统的可扩展性和适应性,为未来可能的需求做好准备。


    Spring Cloud 微服务系列 完整的代码在仓库的sourcecode/spring-cloud-demo目录下。

    gitee(推荐):https://gitee.com/cunzaizhe/xiaohuge-blog

    github:https://github.com/tigerleeli/xiaohuge-blog

    关注微信公众号:“小虎哥的技术博客”,让我们一起成为更优秀的程序员❤️!

  • 相关阅读:
    第14届蓝桥杯省赛 ---- C/C++ C组
    前后端分离项目,vue+uni-app+php+mysql在线考试系统(H5移动项目) 开题报告
    码题集习题
    Python 数独求解器
    Bioinformatics2019 | FP2VEC+:基于新分子特征的分子性质预测
    MySQL基础篇【第五篇】| union、limit、DDL、DML、约束
    第30集丨本来的面目:认识你自己
    类与对象(初级)
    gitlab 搭建使用
    el-table的border属性失效问题解决方案
  • 原文地址:https://blog.csdn.net/qq_28883885/article/details/133746512