2024.5.6 Monday
Continuing from 【WEEK10】 【DAY2】Employee Management System Part 1【English Version】
Contents
- 10.3. Page Internationalization
- 10.3.1. Preparation
- 10.3.2. Configuration File Writing
- 10.3.2.1. Create an i18n (abbreviation for internationalization) directory under the resources folder
- 10.3.2.2. Create the files login.properties and login_zh_CN.properties in the i18n folder
- 10.3.2.3. Import Configuration Files
- 10.3.2.4. Add Key-Value Pairs
- 10.3.3. Configuration File Activation Exploration
- 10.3.4. Configuring Page Internationalization Values
- 10.3.4.1. Modify the index.html page
- 10.3.5. Configuring Internationalization Resolution
- 10.3.5.1. In Spring, there is an internationalization Locale (regional information object)
- 10.3.5.2. Go to the webmvc auto-configuration file
- 10.3.5.3. Modify the index.html
- 10.3.5.4. Create MyLocaleResolver.java
- 10.3.5.5. Modify MyMvcConfig.java
- 10.3.5.6. Restart and Refresh
- 10.3.6. Summary
10.3. Page Internationalization
Sometimes, our website will involve switching between Chinese and English or even multiple languages. That’s when we need to learn about internationalization!
10.3.1. Preparation
First, set the encoding for properties files to UTF-8 in IDEA! (File | Settings | Editor | File Encodings)
Change them all to UTF-8
Write the internationalization configuration file to extract the internationalized page messages that need to be displayed on the page. We can go to the login page to see what content we need to write internationalization configurations for!
10.3.2. Configuration File Writing
10.3.2.1. Create an i18n (abbreviation for internationalization) directory under the resources folder
To store internationalization configuration files
10.3.2.2. Create the files login.properties and login_zh_CN.properties in the i18n folder
IDEA will automatically recognize and generate the new folder
*If these two files are not automatically merged: you need to download the Resource Bundle Editor plugin
10.3.2.3. Import Configuration Files
Find that login_en_US.properties was generated
10.3.2.4. Add Key-Value Pairs
Click Resource Bundle to enter a visual interface
Similarly
Finally, five sets of values were added, and the corresponding files will automatically generate code:
login.properties
login.button=Login
login.password=Password
login.remember=Remember Me
login.tip=Please Login
login.username=Username
login_en_US.properties
login.button=Sign in
login.password=Password
login.remember=Remember me
login.tip=Please sign in
login.username=Username
login_zh_CN.properties
login.button=登录
login.password=密码
login.remember=记住我
login.tip=请登录
login.username=用户名
10.3.3. Configuration File Activation Exploration
Let’s take a look at SpringBoot’s autoconfiguration for internationalization! Here it involves a class: MessageSourceAutoConfiguration.java
There is a method inside, and here we find that SpringBoot has already automatically configured a component to manage our internationalization resource files, ResourceBundleMessageSource
@Bean
@ConfigurationProperties(prefix = "spring.messages")
public MessageSourceProperties messageSourceProperties() {
return new MessageSourceProperties();
}
// Get the values passed from properties to make judgments
@Bean
public MessageSource messageSource(MessageSourceProperties properties) {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
if (StringUtils.hasText(properties.getBasename())) {
// Set the base name of the internationalization file (excluding the language and country code)
messageSource.setBasenames(StringUtils
.commaDelimitedListToStringArray(StringUtils.trimAllWhitespace(properties.getBasename())));
}
if (properties.getEncoding() != null) {
messageSource.setDefaultEncoding(properties.getEncoding().name());
}
messageSource.setFallbackToSystemLocale(properties.isFallbackToSystemLocale());
Duration cacheDuration = properties.getCacheDuration();
if (cacheDuration != null) {
messageSource.setCacheMillis(cacheDuration.toMillis());
}
messageSource.setAlwaysUseMessageFormat(properties.isAlwaysUseMessageFormat());
messageSource.setUseCodeAsDefaultMessage(properties.isUseCodeAsDefaultMessage());
return messageSource;
}
As the actual configuration is placed in the i18n directory, it is necessary to configure the path for these messages -> modify the application.properties
file
spring.application.name=springboot-03-web2
#spring.mvc.favicon.enabled=false this method is already deprecated
#Turn off the cache of the template engine
spring.thymeleaf.cache=false
#Modify the access URL, at this time to access the homepage, the URL that needs to be entered has changed to: http://localhost:8080/111/
#server.servlet.context-path=/111
#Modify the recognition address of basename (from the default MessageSourceProperties file to i18n.login)
spring.messages.basename=i18n.login
10.3.4. Configuring Page Internationalization Values
To retrieve internationalization values on the page, consult the Thymeleaf documentation to find that the message retrieval operation is: #{…}.
10.3.4.1. Modify the index.html page
Lines to be modified: 18~22, 25, 28.
<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1>
<label class="sr-only" th:text="#{login.username}">Username</label>
<input type="text" class="form-control" th:placeholder="#{login.username}" required="" autofocus="">
<label class="sr-only" th:text="#{login.password}">Password</label>
<input type="password" class="form-control" th:placeholder="#{login.password}" required="">
<input type="checkbox" value="remember-me"> [[#{login.remember}]]
<button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.button}">Sign in</button>
After restart, the login page:
10.3.5. Configuring Internationalization Resolution
Goal: Automatically switch between Chinese and English according to the button
10.3.5.1. In Spring, there is an internationalization Locale (regional information object)
There is a resolver called LocaleResolver
(to obtain regional information object)!
10.3.5.2. Go to the webmvc auto-configuration file
Find the default SpringBoot configuration:
Line466, click line473 AcceptHeaderLocaleResolver to jump,
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "spring.mvc", name = "locale")
public LocaleResolver localeResolver() {
// If there is no container, configure it yourself; if there is, use the user's configuration
if (this.mvcProperties.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
return new FixedLocaleResolver(this.mvcProperties.getLocale());
}
// Accept header internationalization breakdown
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
return localeResolver;
}
It can be seen that there is a method on line19
public Locale resolveLocale(HttpServletRequest request) {
Locale defaultLocale = this.getDefaultLocale();
// The default is to obtain Locale for internationalization based on the regional information brought by the request header
if (defaultLocale != null && request.getHeader("Accept-Language") == null) {
return defaultLocale;
} else {
Locale requestLocale = request.getLocale();
List<Locale> supportedLocales = this.getSupportedLocales();
if (!supportedLocales.isEmpty() && !supportedLocales.contains(requestLocale)) {
Locale supportedLocale = this.findSupportedLocale(request, supportedLocales);
if (supportedLocale != null) {
return supportedLocale;
} else {
return defaultLocale != null ? defaultLocale : requestLocale;
}
} else {
return requestLocale;
}
}
}
-> If we now want to click on a link to make our internationalization resources take effect, we need to make our own Locale take effect -> try to overwrite it.
10.3.5.3. Modify the index.html
Lines 30, 31
<a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a>
10.3.5.4. Create MyLocaleResolver.java
package com.P14.config;
import org.springframework.web.servlet.LocaleResolver;
import org.thymeleaf.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
public class MyLocaleResolver implements LocaleResolver {
// Resolve the request
@Override
public Locale resolveLocale(HttpServletRequest request) {
// Get the language parameter from the request
String language = request.getParameter("l");
// Use the default if no custom one is defined
Locale locale = Locale.getDefault();
// If the request link carries internationalization parameters
if (!StringUtils.isEmpty(language)){
// Split the request parameters
String[] split = language.split("_");
// Country, region
locale = new Locale(split[0],split[1]);
}
return locale;
}
@Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
}
}
10.3.5.5. Modify MyMvcConfig.java
package com.P14.config;
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.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
//@EnableWebMvc // This imports a class, DelegatingWebMvcConfiguration, which acquires all the webMvcConfig from the container
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// Redirect the following two URLs to the index page file
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
}
// Make the custom internationalization component effective
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
}
10.3.5.6. Restart and Refresh
Chinese:
English:
10.3.6. Summary
- Homepage configuration:
- Note that all pages’ static resources need to be managed by Thymeleaf
- URL: @{}
- Page Internationalization
- We need to configure i18n files
- If we want to automatically switch buttons in the project, we need to define a component
LocaleResolver
- Remember to configure the components you write into the Spring container with
@Bean
- #{}