本文已参与「新人创作礼」活动,一起开启掘金创作之路。
在阅读springboot官方文档spring-boot-reference.pdf的过程中,发现springboot的国际化支持也是非常不错的。前一段时间做了一个项目,需要解决中文、繁体、英文的国际化问题。虽然项目采用了前后端分离,最终通过前端js代码来实现了国际化,但是阅读springboot的解决方式之后,不得不说springboot在这个问题上还是非常便捷的。
1.需求描述和html代码
现在假定需要实现一个登陆业面,使其能支持简体中文、繁体中文和英文登陆。
业面如下:
要实现上述功能的html代码如下:
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="" method="post">
<label>Username</label>
<input type="text" name="username" placeholder="Username">
<label>Password</label>
<input type="password" name="password" placeholder="password" >
<br/>
<div>
<label>
<input type="checkbox" value="remember-me">记住我
</label>
</div>
<button type="submit" >登陆</button>
<br> <br>
<a>中文(简体)</a>
<a>中文(繁体)</a>
<a>English</a>
</form>
</body>
</html>
复制代码
现在很容易就实现了这样一个html,那么下面就通过springboot,配合模板引擎来实现。
2.国际化资源配置
要实现上述文字部分的国际化,首先需要定一需要国际化的资源,也就是哪些位置我们需要做国际化。上述网页中,我们可以将form内的文字内容全部国际化。
在idea中,resources下面创建一个i18n目录来存放这些资源,为什么是i18n呢,i18n(其来源是英文单词 internationalization的首末字符i和n,18为中间的字符数)是“国际化”的简称。因此我们将国际化的资源放置在此目录。需要创建的文件如下:
- login.properties
login.username=用户名1
login.sign=登陆1
login.remember=记住我1
login.password=密码1
复制代码
- login_en_US.properties
login.username=Username
login.sign=Sign in
login.remember=Remember Me
login.password=Password
复制代码
- login_zh_CN.properties
login.username=用户名~
login.sign=登陆~
login.remember=记住我~
login.password=密码~
复制代码
![](/qrcode.jpg)
- login_zh_HK.properties
login.username=用戶名
login.sign=登陸
login.remember=記住我
login.password=密碼
复制代码
这样上述4个国际化文件创建完毕,分别将上述4个字段定义了不同language下的国际化输出。
3.html
现在需要将上述定义的国际化资源配置到html的模板中,此使需要用到thymeleaf模板引擎。
我们将定义一个login.html的文件放置在resources/templates目录。
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="" method="post">
<label th:text="#{login.username}">Username</label>
<input type="text" name="username" placeholder="Username" th:placeholder="#{login.username}">
<label th:text="#{login.password}">Password</label>
<input type="password" name="password" placeholder="password" th:placeholder="#{login.password}">
<br/>
<div>
<label>
<input type="checkbox" value="remember-me">[[#{login.remember}]]
</label>
</div>
<button type="submit" th:text="#{login.sign}">Sign in</button>
<br> <br>
<a th:href="@{/login(language='zh_CN')}">中文(简体)</a>
<a th:href="@{/login(language='zh_HK')}">中文(繁体)</a>
<a th:href="@{/login(language='en_US')}">English</a>
</form>
</body>
</html>
复制代码
4.Controller
配置好上述代码之后,我们只需要定义一个非常简单的MyController类即可:
package com.dhb.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class MyController {
@RequestMapping("login")
public String login() {
return "login";
}
}
复制代码
当然,还需要一个启动类MySpringBootApplication:
package com.dhb;
import com.dhb.servlet.MyServlet;
import com.dhb.servlet.listener.MyHttpSessionListener;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
@ServletComponentScan
public class MySpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(MySpringBootApplication.class, args);
}
//将servlet 添加到springboot容器中
@Bean
public ServletRegistrationBean<MyServlet> webServletRegistrationBean() {
ServletRegistrationBean<MyServlet> bean = new ServletRegistrationBean<>(new MyServlet(),"/s2");
bean.setLoadOnStartup(1);
return bean;
}
@Bean
public ServletListenerRegistrationBean listenerRegistrationBean() {
ServletListenerRegistrationBean srb = new ServletListenerRegistrationBean();
srb.setListener(new MyHttpSessionListener());
System.out.println("listener 创建成功");
return srb;
}
}
复制代码
这样这个国际化问题的demo就基本可以使用了,只需要通过修改浏览器的语言首选项即可:
在chrome的设置-> 高级-> 语言 中进行配置。
只需要将任何一种语言移动到顶部即可。
我们将语言首选项设置为英语之后:
image.png
打开浏览器访问http://127.0.0.1:8084/login效果如下:
这样就实现了多语言的切换。
5.手动选择语言的支持
当然,如果每次都需要按浏览器来调整则显得不那么高大上了,我们需要实现按用户自定义制定的语言来实现多语言切换。
我们需要在上述的p标签中增加:
<a th:href="@{/login(language='zh_CN')}">中文(简体)</a>
<a th:href="@{/login(language='zh_HK')}">中文(繁体)</a>
<a th:href="@{/login(language='en_US')}">English</a>
复制代码
可以看到在点击p标签的内容后将language参数传递到了后端。后端代码中需要定义如下类:
package com.dhb.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ObjectUtils;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
@Configuration
public class MyConfig implements WebMvcConfigurer {
@Bean
public LocaleResolver localeResolver() {
return new NativeLocaleResolver();
}
protected static class NativeLocaleResolver implements LocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest request) {
String language = request.getParameter("language");
System.out.println("language is: " + language);
Locale locale = Locale.getDefault();
if (!ObjectUtils.isEmpty(language)) {
String[] split = language.split("_");
locale = new Locale(split[0], split[1]);
}
return locale;
}
@Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
}
}
}
复制代码
主要是实现一个WebMvcConfigurer的接口,让其初始化一个NativeLocaleResolver。在这个类中构造一个 Locale。实际上 Locale包括两个部分,第一部分是语言,第二部分是国家。
Locale(String language, String country)
通过这个构造函数进行构造,根据需要选择不同的国际化资源来实现。
点击繁体效果如下:
可见,通过springboot来实现国际化配置还是非常方便的。但是目前前后端大多数采用分离架构,因此这个功能也不再像当年struts时代会有非常多的人来使用。