JAVA (Springboot) i18n国际化语言配置

时间:2024-12-07 17:56:46
JAVA i18n国际化语言配置
  • 一、简介
  • 二、功能
  • 三、Java配置国际化步骤
  • 四、Java国际化配置工具类
  • 五、Spring Boot配置
  • 六、测试

一、简介

在Java中,国际化(Internationalization,通常简称为i18n)是一个过程,它允许应用程序适应不同的语言和地区设置,从而能够支持全球用户。Java平台为国际化提供了强大的支持,包括Locale类、ResourceBundle类以及用于格式化日期、数字和货币的类。

二、功能

1.支持多语言:

应用程序可以显示多种语言的文本,包括但不限于英文、中文、法文等。
通过使用ResourceBundle,可以为每种语言提供独立的资源文件(通常是.properties文件),其中包含该语言的文本。

2.自动选择语言:
Java的Locale类允许应用程序根据用户的偏好或系统设置自动选择适当的语言。
例如,如果用户的操作系统设置为法语,那么应用程序将尝试加载法语的资源文件。格式化日期、数字和货币

3.用户手动切换语言:
应用程序通常还允许用户手动切换语言,即使他们的系统设置或浏览器默认语言不是他们想要使用的语言。这可以通过在应用程序中提供语言选择界面或设置选项来实现。

4.前后端文字、校验、消息提醒的国际化:
国际化不仅限于用户界面上的文本,还包括后端代码中的字符串、错误消息、验证提示等。
通过使用外部化的字符串和消息,可以确保整个应用程序的文本都是可翻译的。

5.通过AOP切面实现多语言的配置:
这是一个高级特性,允许开发人员使用面向切面编程(AOP)来自动处理对象的字符串属性,并根据配置文件中的语言设置进行替换。
这种方法可以确保即使在复杂的业务逻辑中,字符串也能被正确地翻译成用户所需的语言。
配置文件命名规则:
在Java国际化中,配置文件必须遵循特定的命名规则,以便Java能够正确识别。
例如,一个名为“messages”的资源束文件可以有以下命名的资源文件:messages.properties(默认)、messages_en_US.properties(英语(美国))、messages_fr_FR.properties(法语(法国))等。

三、Java配置国际化步骤

3.1 创建资源文件夹
在src/main/resources目录下新建一个文件夹,用于存放国际化配置文件。
例如,您可以创建一个名为i18n或messages的文件夹。

3.2 添加语言文件

3.2.1 选择Resource Bundle 进行添加配置文件

在这里插入图片描述
3.2.2 配置要添加的语言配置文件
在i18n或messages文件夹下,为每个要支持的语言和地区添加.properties文件。文件名的命名规则通常是basename_language_country.properties,其中basename是您的基本文件名(如messages),language是ISO 639语言代码(如en代表英语),country是ISO 3166国家代码(如US代表美国)。

例如:
messages_en_US.properties(美国英语)
messages_en_GB.properties(英国英语)
messages_zh_CN.properties(简体中文)
messages_zh_TW.properties(繁体中文,*)

(会有一个Default locale默认的语言配置文件)
在这里插入图片描述

3.2.3、 在对应的配置文件添加对应的语言信息

1.zh_CN:(中文)

sys.config.newParameters=新增参数
sys.config.changeParameters=修改参数
sys.config.newParametersExists=失败,参数键名已存在

2.en_US:(英文)

sys.config.newParameters=New parameters
sys.config.changeParameters=Modify parameters
sys.config.newParametersExists=Failed, parameter key name already exists

四、Java国际化配置工具类

4.1、创建MessageUtils工具类

MessageUtils 工具类在国际化(i18n)应用中扮演着非常重要的角色,它封装了与消息资源相关的常用操作,使得在应用程序的不同部分中都能够方便地获取和格式化本地化消息,而无需重复编写代码,通过key来获取目前系统语言的value值。

import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;

/**
 * 获取i18n资源文件
 *
 * @author cccl
 */
public class MessageUtils {
    /**
     * 根据消息键和参数 获取消息 委托给spring messageSource
     *
     * @param code 消息键
     * @param args 参数
     * @return 获取国际化翻译值
     */
    public static String message(String code, Object... args) {
        MessageSource messageSource = SpringUtils.getBean(MessageSource.class);
        return messageSource.getMessage(code, args, LocaleContextHolder.getLocale());
    }
}

4.2、添加国际化(i18n配置类)

import lombok.extern.slf4j.Slf4j; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.web.servlet.config.annotation.InterceptorRegistration; 
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**  
 * 国际化(i18n)配置类  
 */  
@Configuration   
@Slf4j 
// 实现WebMvcConfigurer接口,用于自定义Spring MVC的配置  
public class I18nConfig implements WebMvcConfigurer { 
  
    /**  
     * 添加拦截器到Spring MVC的拦截器链中  
     *  
     * @param registry 拦截器注册器,用于添加和配置拦截器  
     */  
    @Override  
    public void addInterceptors(InterceptorRegistry registry) {  
        // 创建一个自定义的国际化拦截器实例  
        MyI18nInterceptor myHandlerInterceptor = new MyI18nInterceptor();  
        // 使用拦截器注册器注册自定义的国际化拦截器  
        InterceptorRegistration loginRegistry = registry.addInterceptor(myHandlerInterceptor);  
        // 设置需要拦截的路径模式,这里配置为拦截所有路径("/**")  
        loginRegistry.addPathPatterns("/**");  
    }  
  
}

4.3、添加国际化(i18n拦截器)

import com.github.pagehelper.util.StringUtil;
import lombok.extern.slf4j.Slf4j;  
import org.springframework.context.i18n.LocaleContextHolder;  
import org.springframework.web.servlet.HandlerInterceptor;  
import org.springframework.web.servlet.ModelAndView;  
  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
import java.util.Locale;  
  
/**  
 * i18n拦截器:用于从HTTP请求头中获取国际化参数,并设置当前线程的Locale。  
 */  
@Slf4j  
public class MyI18nInterceptor implements HandlerInterceptor {  
  
    /**  
     * 在请求处理之前进行调用。  
     *  
     * @param request  HttpServletRequest对象,提供对客户端请求信息的访问  
     * @param response HttpServletResponse对象,提供对HTTP响应的控制  
     * @param handler  被调用的处理器,通常是HandlerMethod  
     * @return 如果返回false,则请求处理流程将被中断并返回给客户端;如果返回true,则继续执行后续流程  
     * @throws Exception 抛出异常将中断请求处理流程  
     */  
    @Override  
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {  
        // 假设请求头中存储语言信息的键名为"Language"  
        final String key = "Language"; 
        // 从请求头中获取语言信息  
        String language = request.getHeader(key); 
         // 使用自定义的字符串工具类判断语言信息是否非空  
        if (JoventStringUtils.isNotEmpty(language)) {
            // 假设语言信息格式为"zh_CN"或"en_US",这里通过下划线分割获取语言和地区信息  
            String[] languageParts = language.split("_");  
            // 确保分割后有两个部分  
            if (languageParts.length == 2) { 
                // 创建Locale对象  
                Locale locale = new Locale(languageParts[0], languageParts[1]); 
                // 设置当前线程的Locale  
                LocaleContextHolder.setLocale(locale); 
            } else {  
                // 如果格式不正确,可以记录日志或进行其他处理  
                log.warn("Invalid language format: {}", language);  
            }  
        }  
        // 继续执行后续流程 
        return true;  
    }  
  
    /**  
     * 在请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)  
     * 通常用于处理一些需要在请求处理之后、视图渲染之前执行的逻辑  
     *  
     * @param request   HttpServletRequest对象  
     * @param response  HttpServletResponse对象  
     * @param handler   被调用的处理器  
     * @param modelAndView 如果处理器方法的返回值是ModelAndView类型,则为该方法的返回值,否则为null  
     */  
    @Override  
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {  
        // 可以在这里添加处理请求处理之后、视图渲染之前的逻辑  
    }  
  
    /**  
     * 在整个请求结束之后被调用,也就是在DispatcherServlet渲染了对应的视图之后执行(主要是用于进行资源清理工作)  
     *  
     * @param request   HttpServletRequest对象  
     * @param response  HttpServletResponse对象  
     * @param handler   被调用的处理器  
     * @param ex        如果在请求处理过程中发生异常,则为该异常,否则为null  
     */  
    @Override  
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {  
        // 可以在这里添加请求处理完毕后的清理逻辑,例如关闭资源等  
    }  
}

五、Spring Boot配置

spring:  
  # 资源信息配置  
  messages:  
    # 国际化资源文件的基础名称(不包含文件后缀),Spring将会在这个基础上添加语言代码和地区代码(例如messages_zh_CN.properties)来查找具体的资源文件  
    basename: i18n/messages # 国际化资源文件路径  
  
    # 当找不到特定Locale的资源文件时,是否回退到系统默认的Locale。如果设置为true,并且找不到特定Locale的资源文件,Spring将尝试使用系统默认的Locale来加载资源文件  
    fallback-to-system-locale: true # 回退到系统Locale  
  
    # 指定资源文件的编码格式。在读取资源文件时,Spring将使用此编码格式  
    encoding: UTF-8 # 编码格式  
  
    # 国际化资源文件的缓存时间(以秒为单位)。在这段时间内,相同的资源请求将不会再次加载资源文件,而是从缓存中获取。设置为-1将禁用缓存  
    cache-duration: 3600 # 缓存持续时间(秒)

六、测试

6.1、接口

@Log(title = "参数管理", businessType = BusinessType.INSERT)
@GetMapping("/add")
public AjaxResult add() {
    return AjaxResult.success(MessageUtils.message("sys.config.newParameters"));
}

此处截取的是请求头的Language参数,那么我们在请求的时候添加一个Language参数 (具体的截取字段名自行配置)

6.2 、英文请求(en_US)

在这里插入图片描述
6.3 、中文请求(zh_CN)
在这里插入图片描述