SpringBoot + Spring MVC國際化使用示例


項目中需要顯示中英文兩種語言,所以需要對顯示的內容進行國際化,如下是一個示例程序。

程序文件結構,如下圖,后面詳細列出各文件的代碼。

1. 編寫maven的pom.xml文件,如下:

<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>syb</groupId>
    <artifactId>i18nTest</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>i18nTest</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.1.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

 2. 啟動類如下,重點是聲明了localeResolver,這是國際化功能必須的,注意name屬性不要改。

package syb.i18nTest;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;

@SpringBootApplication
public class App {

    /**
     * 國際化功能需要
     */
    @Bean(name = "localeResolver")
    public LocaleResolver getLocaleResolver() {
        LocaleResolver localeResolver = new SessionLocaleResolver();
        return localeResolver;
    }

    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

 3.  項目中需要方便的控制語言的切換,所以對LocaleChangeInterceptor進行了一下重寫,改為使用session中的locale屬性,控制顯示的語言。並且,默認語言設為了英文。代碼如下。這個修改不是必須的,如果想使用官方默認的方式,請查閱文檔。

package syb.i18nTest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.support.RequestContextUtils;

/**
 * 繼承LocaleChangeInterceptor,重寫其preHandler方法,即在請求處理前,進行的操作。
 * 重寫的preHandler方法,基本上和原方法一致,只是改為使用session中的locale屬性,控制使用的語言。
 * 要使此攔截器生效,需要添加此攔截器,見{@link WebConfig.java}
 */
public class OMCLocaleChangeInterceptor extends LocaleChangeInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 獲取語言,en表示為英文,zh表示為中文
        String newLocale = (String) request.getSession().getAttribute("locale");
        if (newLocale == null || newLocale.length() == 0) {
            newLocale = "en";// 默認語言,設為英文
        }
        if (newLocale != null) {
            // 獲取語言轉換對象
            LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
            if (localeResolver == null) {
                throw new IllegalStateException("No LocaleResolver found: not in a DispatcherServlet request?");
            }
            try {
                // 執行語言轉換操作
                localeResolver.setLocale(request, response, parseLocaleValue(newLocale));
            } catch (IllegalArgumentException ex) {
                if (isIgnoreInvalidLocale()) {
                    logger.debug("Ignoring invalid locale value [" + newLocale + "]: " + ex.getMessage());
                } else {
                    throw ex;
                }
            }
        }
        return true;
    }

}

 4. 添加攔截器,也就是上述步驟中編寫的類,代碼如下。

package syb.i18nTest;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * WEB 配置類,添加國際化的攔截器
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 添加用於國際化語言轉換的攔截器
        registry.addInterceptor(new OMCLocaleChangeInterceptor());
    }
}

 5. 編寫Controller,主要演示的內容:(1)切換語言方法;(2)從后端獲取國際化數據的方法;(3)提供了一個進入頁面的接口,頁面中演示了在前端獲取國際化數據的方法。

package syb.i18nTest;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 一個Controller示例,相當於web模塊的Action
 */
@Controller
public class ControllerTest {
    private Logger logger = LoggerFactory.getLogger(getClass());
    
    @Autowired
    private HttpServletRequest request;
    
    /**
     * 用於獲取國際化數據
     */
    @Autowired
    private MessageSource messageSource;
    
    /**
     * 切換語言的方法
     */
    @RequestMapping("/setLocale/{locale}")
    @ResponseBody
    public Map<String, String> setLocale(@PathVariable String locale) {
        logger.info("set locale to " + locale);
        
        // 通過session中的locale屬性,控制使用的語言
        request.getSession().setAttribute("locale", locale);
        
        Map<String, String> msgMap = new HashMap<>();
        msgMap.put("type", "Info");
        msgMap.put("msg", "OK, To " + locale);
        return msgMap;
    }

    /**
     * 進入頁面,並演示如何在后端獲取國際化數據
     */
    @RequestMapping("/main")
    public String toMain(Model model) {
        // 后端獲取國際化數據,並打印
        String projectName = messageSource.getMessage("projectName", null, LocaleContextHolder.getLocale());
        logger.info("projectName: " + projectName);
        return "main";
    }
}

6. jquery.min.js即是jquery的js庫文件,不必說明了。

7. main.html即為頁面文件,演示了:(1)前端如何獲取國際化數據,並賦值到js變量中,或者顯示到頁面中;(2)前端發起請求,切換顯示的語言。具體代碼如下:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"></meta>
<title>Spring Boot Web</title>
<script type="text/javascript" th:src="@{js/jquery.min.js}"></script>
<script type="text/javascript">
    var projectNameValue = "[[#{projectName}]]";// 取國際化數據,並賦值到js變量

    $(function() {
        // 將獲取到的國際化數據,打印到控制台
        console.info(projectNameValue);
    });

    // 轉換成英文,並刷新頁面
    function toEn() {
        $.post("/setLocale/en", {}, function(result) {
            window.location.reload();
        });
    }

    // 轉換成中文,並刷新頁面
    function toZh() {
        $.post("/setLocale/zh", {}, function(result) {
            window.location.reload()
        });
    }
</script>
</head>
<body>
    <!-- 取國際化數據,並通過span標簽,顯示到頁面上 -->
    <div>
        國際化字符串:<span th:text="#{projectName}"></span>
    </div>

    <!-- 語言切換按鈕 -->
    <div>
        <button onclick="toEn()">To En</button>
        <button onclick="toZh()">To Zh</button>
    </div>
</body>
</html>

 

 8. messages*.properties,是具體的國際化項的配置,三個文件代碼分別為:

# messages.properties

projectName=Spring Boot Hello World
# messages_zh.properties

projectName=Spring Boot\u5C0F\u7A0B\u5E8F
# messages_en.properties

projectName=Spring Boot Hello World

 

 9. 啟動程序,瀏覽器中輸入地址:http://localhost:8080/main。

后端日志中打印:projectName: Spring Boot Hello World,說明后端獲取國際化數據沒有問題。

頁面中顯示如圖:

可以看到頁面中顯示了國際化數據,瀏覽器控制台中也正確打印國際化數據。

10. 可以點擊頁面上的兩個按鈕,觀察語言的切換功能。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM