建立多语言网站,可以获得更多用户流量。多语言网站被称为国际化(i18n),与本地化相反。
你比如京东、淘宝这类电商网站就是国际化的电商网站,它支持多国语言。
注意: 国际化是一个由18个字符组成的单词,第一个字符为i,最后一个字符为n,因此通常缩写为 i18n。
Spring通过为不同的语言环境使用Spring拦截器,语言环境解析器和资源包,为国际化(i18n)提供了广泛的支持。在本文中,我将知道您使用Spring Boot构建了一个简单的多语言网站。
你可以预览一下示例:
在示例中,语言环境信息位于URL的参数上。语言环境信息将存储在Cookie中,并且用户不会在接下来的页面中重新选择语言。
URL上的语言环境信息的另一个示例:
我在这里为以下语言创建2个属性文件:中文、英语。
i18n / messages_zh.properties
label.password=密码
label.submit=登陆label.title= 登陆页面label.userName=用户名
如果你的eclipse中显示如下编码形式:
label.password=\u5BC6\u7801
label.submit=\u767B\u9646label.title= \u767B\u9646\u9875\u9762label.userName=\u7528\u6237\u540D
修改首选项中的content Types下的:
第二步配置.proerties文件右键属性配置,设置其字符编码
i18n / messages_en.properties
label.password= Password
label.submit= Loginlabel.title= Login Pagelabel.userName= User Name
Eclipse支持使用消息编辑器来编辑文件的信息。
您需要声明2个Spring bean,包括localeResolver和messageResource。
LocaleResolver指定如何获取用户将使用的语言环境信息。CookieLocaleResolver将从Cookie读取语言环境信息,以查找用户以前使用的语言。
MessageResource 将加载属性文件内容
在Controller处理请求之前,它必须经过拦截器,您需要在该拦截器中注册LocaleChangeInterceptor,拦截器处理用户的语言环境更改。
WebMvcConfig.JAVA
package me.laocat.i18n.config;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
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.CookieLocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Bean(name = “localeResolver”)
public LocaleResolver getLocaleResolver() {
// Cookie本地化解析器
CookieLocaleResolver resolver = new CookieLocaleResolver();
resolver.setCookieDomain(“myAppLocaleCookie”);
// 60 分钟
resolver.setCookieMaxAge(60 * 60);
return resolver;
}
@Bean(name = “messageSource”)
public MessageSource getMessageResource() {
// 可重新加载的资源包消息源
ReloadableResourceBundleMessageSource messageResource = new ReloadableResourceBundleMessageSource();
// 读 i18n/messages_xxx.properties file.
// 例如: i18n/messages_en.properties
messageResource.setBasename(“classpath:i18n/messages”);
messageResource.setDefaultEncoding(“UTF-8”);
return messageResource;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 本地化修改拦截器
LocaleChangeInterceptor localeInterceptor = new LocaleChangeInterceptor();
localeInterceptor.setParamName(“lang”);
registry.addInterceptor(localeInterceptor).addPathPatterns(“/*”);
}
}
I18nController.java(在参数上设置本地化)
package me.laocat.i18n;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class I18nController {
@RequestMapping(value = { “/”, “/login1” })
public String staticResource(Model model) {
return “login1”;
}}
login1.html (Thymeleaf 视图)
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title th:utext="#{label.title}"></title>
</head>
<body>
<div style="text-align: right;padding:5px;margin:5px 0px;background:#ccc;">
<a th:href="@{/login1?lang=en}">Login (En)</a>
| <a th:href="@{/login1?lang=zh}">Login (Zh)</a>
</div>
<form method="post" action="">
<table>
<tr>
<td>
<strong th:utext="#{label.userName}"></strong>
</td>
<td><input name="userName" /></td>
</tr>
<tr>
<td>
<strong th:utext="#{label.password}"></strong>
</td>
<td><input name="password" /></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" th:value="#{label.submit}" />
</td>
</tr>
</table>
</form>
</body>
</html>
如果您要构建一个多语言网站,其语言环境信息位于URL上。您需要更改一些配置:
创建2个类UrlLocaleInterceptor和UrlLocaleResolver
UrlLocaleInterceptor.java
package me.laocat.i18n.interceptors;
import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.servlet.support.RequestContextUtils;
public class UrlLocaleInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);if (localeResolver == null) {
throw new IllegalStateException(“找不到LocaleResolver:不在DispatcherServlet请求中??”);
}// 从LocaleResolver获取区域设置
Locale locale = localeResolver.resolveLocale(request);
localeResolver.setLocale(request, response, locale);
return true;
}
}
UrlLocaleResolver.java
package me.laocat.i18n.resolver;
import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
@Configuration
public class UrlLocaleResolver implements LocaleResolver {
private static final String URL_LOCALE_ATTRIBUTE_NAME = “URL_LOCALE_ATTRIBUTE_NAME”;
@Bean(name = “messageSource”)
@Override
public Locale resolveLocale(HttpServletRequest request) {
// ==> /SomeContextPath/en/…
// ==> /SomeContextPath/zh/…
// ==> /SomeContextPath/WEB-INF/pages/…
String uri = request.getRequestURI();
System.out.println(“URI=” + uri);
String prefixEn = request.getServletContext().getContextPath() + “/en/”;
String prefixZh = request.getServletContext().getContextPath() + “/zh/”;
Locale locale = null;
// English
if (uri.startsWith(prefixEn)) {
locale = Locale.ENGLISH;
}
// China
else if (uri.startsWith(prefixZh)) {
locale = new Locale(“zh”, “CN”);
}
if (locale != null) {
request.getSession().setAttribute(URL_LOCALE_ATTRIBUTE_NAME, locale);
}
if (locale == null) {
locale = (Locale) request.getSession().getAttribute(URL_LOCALE_ATTRIBUTE_NAME);
if (locale == null) {
locale = Locale.ENGLISH;
}
}
return locale;
}
@Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
// Nothing
}
}
重新更改WebMvcConfig中的Interceptor配置 :
WebMvcConfig.java
package me.laocat.i18n.config;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
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.CookieLocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import me.laocat.i18n.interceptors.UrlLocaleInterceptor;
import me.laocat.i18n.resolver.UrlLocaleResolver;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Bean(name = “localeResolver”)
public LocaleResolver getLocaleResolver() {
// Cookie本地化解析器
// CookieLocaleResolver resolver = new CookieLocaleResolver();
// resolver.setCookieDomain(“myAppLocaleCookie”);
// 60 分钟
// resolver.setCookieMaxAge(60 * 60);
LocaleResolver resolver = new UrlLocaleResolver();
return resolver;
}
@Bean(name = “messageSource”)
public MessageSource getMessageResource() {
// 可重新加载的资源包消息源
ReloadableResourceBundleMessageSource messageResource = new ReloadableResourceBundleMessageSource();
// 读 i18n/messages_xxx.properties file.
// 例如: i18n/messages_en.properties
messageResource.setBasename(“classpath:i18n/messages”);
messageResource.setDefaultEncoding(“UTF-8”);
return messageResource;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 本地化修改拦截器
// LocaleChangeInterceptor localeInterceptor = new LocaleChangeInterceptor();
// localeInterceptor.setParamName(“lang”);
// registry.addInterceptor(localeInterceptor).addPathPatterns(“/*”);
UrlLocaleInterceptor localeInterceptor = new UrlLocaleInterceptor();
registry.addInterceptor(localeInterceptor).addPathPatterns(“/en/*”, “/zh/*”);
}
}
控制器:
I18nController2.java(URL上的语言环境)
package me.laocat.i18n.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class I18nController2 {
@RequestMapping(value = “/{locale:en|zh}/login2”)
public String login2(Model model) {
return “login2”;
}}
login2.html (Thymeleaf 视图)
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title th:utext="#{label.title}"></title>
</head>
<body>
<div style="text-align: right;padding:5px;margin:5px 0px;background:#ccc;">
<a th:href="@{/en/login2}">Login (English)</a>
| <a th:href="@{/zh/login2}">Login (China)</a>
</div>
<form method="post" action="">
<table>
<tr>
<td>
<strong th:utext="#{label.userName}"></strong>
</td>
<td><input name="userName" /></td>
</tr>
<tr>
<td>
<strong th:utext="#{label.password}"></strong>
</td>
<td><input name="password" /></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" th:value="#{label.submit}" />
</td>
</tr>
</table>
</form>
</body>
</html>
运行应用程序:
http://localhost:8080/zh/login2
上面的多语言网站示例无法满足您的需求。您需要具有多种语言的新闻网站,并且其内容存储在数据库中。您可以使用多个数据源的解决方案,其中每个数据源都是一个包含语言内容的数据库。