SpringBoot 国际化实现跨地区的多语言切换

1.创建 Spring Boot + Kotlin + Maven 项目

chenguangjian:i18n-demo jack$ tree 
.
├── HELP.md
├── i18n-demo.iml
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
    ├── main
    │   ├── kotlin
    │   │   └── com
    │   │       └── example
    │   │           └── i18ndemo
    │   │               ├── Application.kt
    │   │               ├── IndexController.kt
    │   │               ├── LocaleConfig.kt
    │   │               └── LocaleMessage.kt
    │   └── resources
    │       ├── application.properties
    │       ├── i18n
    │       │   ├── messages.properties
    │       │   ├── messages_en_US.properties
    │       │   └── messages_zh_CN.properties
    │       ├── static
    │       └── templates
    │           └── index.ftlh
    └── test
        └── kotlin
            └── com
                └── example
                    └── i18ndemo
                        └── ApplicationTests.kt

15 directories, 15 files

2.添加pom.xml依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>i18n-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>i18n-demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <kotlin.version>1.3.72</kotlin.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-kotlin</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-reflect</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-stdlib-jdk8</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
    </dependencies>

    <build>
        <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
        <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.jetbrains.kotlin</groupId>
                <artifactId>kotlin-maven-plugin</artifactId>
                <configuration>
                    <args>
                        <arg>-Xjsr305=strict</arg>
                    </args>
                    <compilerPlugins>
                        <plugin>spring</plugin>
                    </compilerPlugins>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.jetbrains.kotlin</groupId>
                        <artifactId>kotlin-maven-allopen</artifactId>
                        <version>${kotlin.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>

</project>

3.IndexController.kt

package com.example.i18ndemo

import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Controller
import org.springframework.ui.ModelMap
import org.springframework.web.bind.annotation.RequestMapping

/**
 * @author: Jack
 * 2020/10/16 14:42
 */
@Controller
class IndexController {
    @Autowired
    lateinit var localeMessage: LocaleMessage

    @RequestMapping(value = ["/", ""])
    fun hello(model: ModelMap): String {
        val welcome = localeMessage.getMessage("welcome")
        model.addAttribute("welcome", welcome)
        return "index"
    }
}

4.封装国际化工具类 LocaleMessage.kt

package com.example.i18ndemo

import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.MessageSource
import org.springframework.context.i18n.LocaleContextHolder
import org.springframework.stereotype.Component
import java.util.*


/**
 * 封装国际化工具类
 * @author: Jack
 * 2020/10/16 16:21
 */
@Component
class LocaleMessage {
    @Autowired
    lateinit var messageSource: MessageSource

    fun getMessage(code: String): String? {
        val locale: Locale = LocaleContextHolder.getLocale()
        return messageSource.getMessage(code, null, null, locale)
    }

}

5.本地化配置类 LocaleConfig.kt

package com.example.i18ndemo

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
import java.util.*

/**
 * 本地化配置类
 *
 * @author: Jack
 * 2020/10/16 17:08
 */
@Configuration
class LocaleConfig {

    /**
     * 默认解析器,其中locale表示默认语言
     */
    @Bean
    fun localeResolver(): LocaleResolver {
        val sessionLocaleResolver = SessionLocaleResolver()
        sessionLocaleResolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE)
        sessionLocaleResolver.setTimeZoneAttributeName("GMT+8")
        return sessionLocaleResolver
    }

    /**
     * 默认拦截器,其中lang表示切换语言的参数名
     */
    @Bean
    fun localeInterceptorConfigurer(): WebMvcConfigurer {
        return object : WebMvcConfigurer {
            override fun addInterceptors(registry: InterceptorRegistry) {
                val localeInterceptor = LocaleChangeInterceptor()
                localeInterceptor.paramName = "lang"
                registry.addInterceptor(localeInterceptor)
            }
        }
    }

}

6.配置语言文案

创建文件夹 resources/i18n , 创建文件:
messages.properties

welcome=你好,世界

messages_en_US.properties

welcome=Hello,World

messages_zh_CN.properties

welcome=你好,世界

7.配置 application.properties

spring.messages.basename=i18n/messages
spring.messages.encoding=UTF-8
spring.messages.cache-duration=3600
spring.freemarker.suffix=.ftlh
spring.freemarker.charset=UTF-8
spring.freemarker.enabled=true
spring.freemarker.allow-session-override=true
spring.freemarker.expose-session-attributes=true

8. 模板文件 templates/index.ftlh

<a href="?lang=en_US"> 英语</a>
<a href="?lang=zh_CN"> 中文</a>
<h1>${welcome}</h1>

9.启动测试 Application.kt

package com.example.i18ndemo

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration
import org.springframework.boot.runApplication

@SpringBootApplication(exclude = [ErrorMvcAutoConfiguration::class])
class Application

fun main(args: Array<String>) {
    runApplication<Application>(*args)
}

http://127.0.0.1:8080/?lang=en_US

http://127.0.0.1:8080/?lang=zh_CN


Kotlin开发者社区

专注分享 Java、 Kotlin、Spring/Spring Boot、MySQL、redis、neo4j、NoSQL、Android、JavaScript、React、Node、函数式编程、编程思想、"高可用,高性能,高实时"大型分布式系统架构设计主题。

High availability, high performance, high real-time large-scale distributed system architecture design

分布式框架:Zookeeper、分布式中间件框架等
分布式存储:GridFS、FastDFS、TFS、MemCache、redis等
分布式数据库:Cobar、tddl、Amoeba、Mycat
云计算、大数据、AI算法
虚拟化、云原生技术
分布式计算框架:MapReduce、Hadoop、Storm、Flink等
分布式通信机制:Dubbo、RPC调用、共享远程数据、消息队列等
消息队列MQ:Kafka、MetaQ,RocketMQ
怎样打造高可用系统:基于硬件、软件中间件、系统架构等一些典型方案的实现:HAProxy、基于Corosync+Pacemaker的高可用集群套件中间件系统
Mycat架构分布式演进
大数据Join背后的难题:数据、网络、内存和计算能力的矛盾和调和
Java分布式系统中的高性能难题:AIO,NIO,Netty还是自己开发框架?
高性能事件派发机制:线程池模型、Disruptor模型等等。。。

合抱之木,生于毫末;九层之台,起于垒土;千里之行,始于足下。不积跬步,无以至千里;不积小流,无以成江河。

Kotlin 简介

Kotlin是一门非研究性的语言,它是一门非常务实的工业级编程语言,它的使命就是帮助程序员们解决实际工程实践中的问题。使用Kotlin 让 Java程序员们的生活变得更好,Java中的那些空指针错误,浪费时间的冗长的样板代码,啰嗦的语法限制等等,在Kotlin中统统消失。Kotlin 简单务实,语法简洁而强大,安全且表达力强,极富生产力。

Java诞生于1995年,至今已有23年历史。当前最新版本是 Java 9。在 JVM 生态不断发展繁荣的过程中,也诞生了Scala、Groovy、Clojure 等兄弟语言。

Kotlin 也正是 JVM 家族中的优秀一员。Kotlin是一种现代语言(版本1.0于2016年2月发布)。它最初的目的是像Scala那样,优化Java语言的缺陷,提供更加简单实用的编程语言特性,并且解决了性能上的问题,比如编译时间。 JetBrains在这些方面做得非常出色。

Kotlin语言的特性

用 Java 开发多年以后,能够尝试一些新的东西真是太棒了。如果您是 Java 开发人员,使用 Kotlin 将会非常自然流畅。如果你是一个Swift开发者,你将会感到似曾相识,比如可空性(Nullability)。 Kotlin语言的特性有:

1.简洁

大幅减少样板代码量。

2.与Java的100%互操作性

Kotlin可以直接与Java类交互,反之亦然。这个特性使得我们可以直接重用我们的代码库,并将其迁移到 Kotlin中。由于Java的互操作性几乎无处不在。我们可以直接访问平台API以及现有的代码库,同时仍然享受和使用 Kotlin 的所有强大的现代语言功能。

3.扩展函数

Kotlin 类似于 C# 和 Gosu, 它提供了为现有类提供新功能扩展的能力,而不必从该类继承或使用任何类型的设计模式 (如装饰器模式)。

4.函数式编程

Kotlin 语言一等支持函数式编程,就像Scala一样。具备高阶函数、Lambda 表达式等函数式基本特性。

5.默认和命名参数

在Kotlin中,您可以为函数中的参数设置一个默认值,并给每个参数一个名称。这有助于编写易读的代码。

6.强大的开发工具支持

而由于是JetBrains出品,我们拥有很棒的IDE支持。虽然Java到Kotlin的自动转换并不是100% OK 的,但它确实是一个非常好的工具。使用 IDEA 的工具转换Java代码为 Kotlin 代码时,可以轻松地重用60%-70%的结果代码,而且修改成本很小。

Kotlin 除了简洁强大的语法特性外,还有实用性非常强的API以及围绕它构建的生态系统。例如:集合类 API、IO 扩展类、反射API 等。同时 Kotlin 社区也提供了丰富的文档和大量的学习资料,还有在线REPL。

A modern programming language that makes developers happier. Open source forever

图来自《Kotlin从入门到进阶实战》 (陈光剑,清华大学出版社)
图来自《Kotlin从入门到进阶实战》 (陈光剑,清华大学出版社)

https://kotlinlang.org/

猜你喜欢

转载自blog.csdn.net/universsky2015/article/details/109130794