Spring Boot国际化实现及配置文件路径设置避坑指南

Spring Boot国际化配置过程

Spring MVC中提供了MessageSource国际化消息源机制,其主要作用为装载国际化消息。这里一般使用JDK的ResourceBundleMessageSource进行处理,在设置国际化时,这里无需配置。

Spring Boot中默认使用的国际化配置文件为messages.properties,该文件在开启国际化时必须创建,否则Spring MVC将不启用国际化消息机制。但该文件的名称可以进行自定义(后续会说明)。此外,中文配置文件和英文配置文件名如下:

  • messages_zh_CN.properties
  • messages_en_US.properties

Spring MVC中提供的国际化解析器(用于解析用户使用的国际区域是哪里)包含如下几个:

  1. AcceptHeaderLocaleResolver:根据浏览器的请求头来确定国际化区域
  2. FixedLocaleResolver:设置固定的国际化区域
  3. CookieLocaleResolver:使用cookie设置国际化区域
  4. SessionLocaleResolver :使用session设置国际化区域

当使用AcceptHeaderLocaleResolver或FixedLocaleResolver来实现国际化的时候,只需要在application.properties配置文件中进行如下的相关设置,既可以实现国际化,无需其他的开发工作:

# 指定国际化区域,可以覆盖Accept-Language请求头信息
spring.mvc.locale=
# 国际化解析器,可以选择fixed或accpet-header
# fixed代表固定的国际化区域,accept-header表示读取浏览器的Accept-Language请求头信息
spring.mvc.locale-resolver=accept-header

使用SessionLocaleResolver实现国际化

当使用session和cookie来实现国际化时比较类似,这里以session为例实现国际化。

1. 配置国际化消息

在application.properties配置文件中进行如下配置:

# Spring MVC国际化配置
# 设置文件编码
spring.messages.encoding=UTF-8
# 国际化文件基础名称
spring.messages.basename=international
# 国际化消息缓存有效时间(单位为秒),超时将重新载入
spring.messages.cache-duration=3600

划重点,其中spring.messages.basename配置项即为指定国际化配置文件所在的目录和名称,即不再使用默认的messages名称,而是使用international,因此相应的配置文件的前缀应该为international。


关于该项配置的避坑指南:例如这里仅设置为international,则国际化相应的配置文件必须在src/main/resources目录下(注意:不能再该目录的子目录下)。但如果你想把国际化的相关配置文件放在resources目录下的某个子目录下,例如放在如下子目录:

则需要修改上面的basename的配置为:

# 国际化文件基础名称
spring.messages.basename=properties/international

也就是basename配置的其实为国际化配置文件所在的目录和文件名前缀。如果上述设置出错,则会产生如下的错误提示:

springboot org.springframework.context.NoSuchMessageException: No message found under code 'msg' for locale 'zh_CN'.

正确完成以上配置文件basename的设置后,开始配置如下的三个国际化配置文件:

# properties/international.properties
# 中文:Spring MVC国际化
msg=Spring MVC\u56fd\u9645\u5316

properties/international_en_US.properties
# 英文Spring MVC internationalization
msg=Spring MVC internationalization

properties/international_zh_CN.properties
# 中文:Spring MVC国际化
msg=Spring MVC\u56fd\u9645\u5316

这样,Spring MVC就会读入这些配置的国际化信息。

2. 创建国际化解析器

这里使用Spring MVC 提供的LocaleChangeInterceptor拦截器,它可以在处理器前执行相关的逻辑,也就是拦截器的preHandle方法的作用。这个拦截器可以设置一个拦截的国际化参数,通过这个参数确定需要使用的国际化区域和相关信息,并将国际化信息保持到session中。该拦截器的实现如下:

@Configuration
public class MyWebMvcConfiguration implements WebMvcConfigurer {

    /**
     * 国际化参数拦截器
     */
    private LocaleChangeInterceptor localeChangeInterceptor;

    /**
     * 注册自定义拦截器方法
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册国际化参数拦截器
        // 这里将通过国家化拦截器的preHandle方法对请求的国际化区域参数进行修改
        registry.addInterceptor(localeChangeInterceptor());

    }

    /**
     * 国际化解析器BEAN,注意这个Bean的名称必须为localeResolver
     */
    @Bean(name = "localeResolver")
    public LocaleResolver initLocaleResolver() {
        SessionLocaleResolver sessionLocaleResolver = new SessionLocaleResolver();
        // 设置默认的国际化区域
        sessionLocaleResolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);
        return sessionLocaleResolver;
    }

    /**
     * 给处理器添加国际化参数拦截器
     * 拦截的参数名称为:language
     */
    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {
        if (localeChangeInterceptor != null) {
            return localeChangeInterceptor;
        }
        localeChangeInterceptor = new LocaleChangeInterceptor();
        // 设置拦截的参数名
        localeChangeInterceptor.setParamName("language");
        return localeChangeInterceptor;
    }

}

3. 实现国际化控制器和视图页面

上述过程已经完成了国际化的内容,下面创建一个controller来进行测试:

@Controller
@RequestMapping("/international")
public class InternationalController {

    /**
     * 注入国际化消息接口对象
     */
    @Autowired
    private MessageSource messageSource;

    /**
     * 获取国际化信息和打开国际化视图
     */
    @RequestMapping("/page")
    public String page(HttpServletRequest request) {
        // 后台获取国际化区域
        Locale locale = LocaleContextHolder.getLocale();
        // 获取国际化配置文件中设置的国际化消息,使用msg标志进行寻找
        String msg = messageSource.getMessage("msg", null, locale);
        System.out.println("msg=" + msg);
        // 返回国际化视图
        return "international";
    }
}

相应的国际化视图页面使用JSP实现,如下:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="mvc" uri="http://www.springframework.org/tags/form" %>
<%@taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%--
  Created by IntelliJ IDEA.
  User: yitian
  Date: 2020-01-29
  Time: 20:40
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Spring MVC international</title>
    <link rel="stylesheet" type="text/css" href="/static/jquery-easyui-1.7.0/themes/default/easyui.css">
    <link rel="stylesheet" type="text/css" href="/static/jquery-easyui-1.7.0/themes/icon.css">
    <script type="text/javascript" src="/static/jquery-easyui-1.7.0/jquery.min.js"></script>
    <script type="text/javascript" src="/static/jquery-easyui-1.7.0/jquery.easyui.min.js"></script>
    <script src="https://code.jquery.com/jquery-3.2.0.js"></script>
    <script type="text/javascript">

    </script>
</head>
<body>
    通过HTTP请求改变国际化:<br>
    <a href="./page?language=zh_CN">简体中文</a>
    <a href="./page?language=en_US">美国英文</a>
    <h2><spring:message code="msg" /></h2> <br>
    当前的国际化区域Locale为: ${pageContext.response.locale}

    <div><a href="http://localhost:8080/web/index">返回首页</a></div>
</body>
</html>

运行项目,得到的international.jsp页面如下:(左侧页面为默认的中文页面,或者点击“简体中文”链接,右侧页面为点击“美国英文”得到的国际化页面)。

 

根据上图可以看到,视图的国际化已经可以通过language参数进行切换,但需要注意的是,此时国际化参数已经保存到session中,所以即使没有这个参数,也会从session中读取该参数设置国际化区域,而当3600秒后session才会失效。

发布了296 篇原创文章 · 获赞 35 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/yitian_z/article/details/104144924