SpringBoot -> 国际化(i18n)

发布时间:2024-02-26 10:00

文章目录

    • 上结果
    • 1.准备工作
    • 配置文件编写
    • 配置文件生效探究
    • 配置页面国际化值
    • 配置国际化解析
    • 总结:我可能骗了你们,这个看了我都总结不出什么东西

上结果

SpringBoot -> 国际化(i18n)_第1张图片SpringBoot -> 国际化(i18n)_第2张图片

1.准备工作

先在IDEA中统一设置properties的编码问题!
SpringBoot -> 国际化(i18n)_第3张图片
编写国际化配置文件,抽取页面需要显示的国际化页面消息。我们可以去登录页面查看一下,哪些内容我们需要编写国际化的配置!

配置文件编写

1、我们在resources资源文件下新建一个i18n目录,存放国际化配置文件
**为什么是i18n的目录:**英语单词中i后面有18个字母最后一个是n,所以是i18n
SpringBoot -> 国际化(i18n)_第4张图片

2、建立一个login.properties文件,还有一个login_zh_CN.properties;发现IDEA自动识别了我们要做国际化操作;文件夹变了!
SpringBoot -> 国际化(i18n)_第5张图片
3、我们可以在这上面去新建一个文件;
SpringBoot -> 国际化(i18n)_第6张图片
弹出如下页面:我们再添加一个英文的;
SpringBoot -> 国际化(i18n)_第7张图片
这样就快捷多了!
SpringBoot -> 国际化(i18n)_第8张图片
4、接下来,我们就来编写配置,我们可以看到idea下面有另外一个视图;
SpringBoot -> 国际化(i18n)_第9张图片
这个视图我们点击 + 号就可以直接添加属性了;我们新建一个login.tip,可以看到边上有三个文件框可以输入
SpringBoot -> 国际化(i18n)_第10张图片
我们添加一下首页的内容!然后依次添加其他页面内容即可!
名字随便起,你看得懂就行
SpringBoot -> 国际化(i18n)_第11张图片
然后去查看我们的配置文件;
login.properties :默认
英文:
中文:
SpringBoot -> 国际化(i18n)_第12张图片
SpringBoot -> 国际化(i18n)_第13张图片
SpringBoot -> 国际化(i18n)_第14张图片
OK,配置文件步骤搞定!

配置文件生效探究

我们去看一下SpringBoot对国际化的自动配置!这里又涉及到一个类:
MessageSourceAutoConfiguration:消息资源自动配置类
里面有一个方法,这里发现SpringBoot已经自动配置好了管理我们国际化资源文件的组件 ResourceBundleMessageSource;

// 获取 properties 传递过来的值进行判断
@Bean
public MessageSource messageSource(MessageSourceProperties properties) {
//自己先new一个东西 资源捆绑消息源
    ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
    //判断还有没有beanname,这个东西是什么我们看看,我找出源码看看,我贴到了这段代码的下面,解释也下面
    if (StringUtils.hasText(properties.getBasename())) {
        // 设置国际化文件的基础名(去掉语言国家代码的)
        messageSource.setBasenames(
        //逗号分隔的列表到字符串数组;commaDelimitedListToStringArray
        //修剪所有空白:trimAllWhitespace
        //就行修剪后搞成数组放到了开始new的资源捆绑消息源中
            StringUtils.commaDelimitedListToStringArray(
                                       StringUtils.trimAllWhitespace(properties.getBasename())));
    }
    //获取编码:getEncoding  如果已经有编码了,就进if
    if (properties.getEncoding() != null) {
    //把你给的编码名字搞出来,又加到new的资源捆绑消息源中
        messageSource.setDefaultEncoding(properties.getEncoding().name());
    }
    //将回退设置为系统区域设置:setFallbackToSystemLocale
    //正在回退到系统区域设置:isFallbackToSystemLocale
    //看不太懂哈;看看注解::设置如果找不到特定区域设置的文件,是否返回到系统区域设置。默认值为“true”;
    //大概就是如果默认是中文的,他找不到就默认中文,找到了,就设置成找到的那个
    messageSource.setFallbackToSystemLocale(properties.isFallbackToSystemLocale());
    //获取缓存持续时间:getCacheDuration
    Duration cacheDuration = properties.getCacheDuration();
    if (cacheDuration != null) {
    //如果有什么叫缓存时间的,就加上去,反正看不懂,好像也没什么关系
        messageSource.setCacheMillis(cacheDuration.toMillis());
    }
    //设置始终使用消息格式:setAlwaysUseMessageFormat
    //总是使用消息格式:isAlwaysUseMessageFormat
    messageSource.setAlwaysUseMessageFormat(properties.isAlwaysUseMessageFormat());
    //将“使用代码”设置为默认消息:setUseCodeAsDefaultMessage
    //默认使用代码:isUseCodeAsDefaultMessage
    messageSource.setUseCodeAsDefaultMessage(properties.isUseCodeAsDefaultMessage());
    return messageSource;
}

getBasename():原来是一个messages的字符串,可以通过getset获取和设置
也就是说,我们也搞个名字反正自己起,然后set一下就可以自定义了,所以等下我们自己配(有点不懂)

	public String getBasename() {
		return this.basename;
	}
public class MessageSourceProperties {
	private String basename = "messages";

总结:他会从properties配置文件中,读取很多的配置,什么时间,什么编码什么
这里我也看不太懂,有点断层
我们真实 的情况是放在了i18n目录下,所以我们要去配置这个messages的路径;
yaml配置走起:

spring:
  messages:
    basename: i18n.login

配置页面国际化值

去页面获取国际化的值,查看Thymeleaf的文档,找到message取值操作为:#{…}。
@{}:这是获取url的
${}:这是变量的
我们去页面测试下:
IDEA还有提示,非常智能的!
SpringBoot -> 国际化(i18n)_第15张图片
我们可以去启动项目,访问一下,发现已经自动识别为中文的了!
SpringBoot -> 国际化(i18n)_第16张图片
但是我们想要更好!可以根据按钮自动切换中文英文!

配置国际化解析

在Spring中有一个国际化的Locale (区域信息对象);
里面有一个叫做LocaleResolver (获取区域信息对象)的解析器!
我们去我们webmvc自动配置文件,寻找一下!看到SpringBoot默认配置:

public class WebMvcAutoConfiguration 
public LocaleResolver localeResolver() {
//始终使用配置的区域设置:FIXED--注解来的哈
//获取区域设置解析程序:getLocaleResolver  这个方法我们也在这段代码下面贴出来解释一下
//看完下面你也知道了,只要我们不是手动自己去set一下LocaleResolver 东西(getLocaleResolver里面的)
//那么左边最终是ACCEPT_HEADER,右边最终是FIXED,绝逼不会相等的,所以我们自定义的就会进这里面
	if (this.webProperties.getLocaleResolver() == WebProperties.LocaleResolver.FIXED) {
	//固定区域解析程序:FixedLocaleResolver  反正都new一个
	//获取区域设置:getLocale  进去看看??  贴到下面
	//肯定了,我们自定义就是走这个的
		return new FixedLocaleResolver(this.webProperties.getLocale());
	}
	//又来了,获取区域设置解析程序:getLocaleResolver()  老规矩,看---
	if (this.mvcProperties.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
	//我又自定义了,我又了来了,没错,只要自定义了都会进这里
	//猜猜这个getLocale是干什么的,我猜跟上面的一样,
	//只不过上面是WebProperties (spring.web) 这个肯定是WebMvcProperties(spring.mvc)(没错我偷偷进去看了)
	//区别就是yaml配置,一个是spring.web.xxx 一个是spring.mvc.xxx
		return new FixedLocaleResolver(this.mvcProperties.getLocale());
	}
	//接受标头区域设置解析程序:AcceptHeaderLocaleResolver  开始了,如果上面两个if都没进去
	AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
	//getLocale这个不是null就走web,是null就走mvc,这...有什么区别吗,web和mvc有啥区别??
	//至少知道的是,为空就走mvc,那是说明mvc肯定有值喽,不然web是空的,再由web赋值,怕不是傻子...
	//然后我去yaml去尝试看了一下,web的local可以正常修改,而mvc的yaml说local已经过时了...tm的
	//但是最后我猜到了,哈哈,没想到吧,我猜这个getLocale获取的是我输入的zh_CN的zh,或者en_US的en
	//因为tm的他们的local都是:要使用的区域设置。默认情况下,此区域设置由“Accept Language”头覆盖。
	//假设是吧,就这样
	Locale locale = (this.webProperties.getLocale() != null) ? this.webProperties.getLocale()
			: this.mvcProperties.getLocale();
	//什么new的AcceptHeaderLocaleResolver  接受标头区域设置解析程序
	//设置默认区域设置setDefaultLocale  设置默认文locale的(他就是中文,或者英文,我说的)
	localeResolver.setDefaultLocale(locale);
	return localeResolver;
}

this.webProperties.getLocaleResolver():所以兜兜绕绕,其实你们两个=都是来自一个enum的

	public LocaleResolver getLocaleResolver() {
		return this.localeResolver;
	}
   private LocaleResolver localeResolver = LocaleResolver.ACCEPT_HEADER;
   	public enum LocaleResolver {
		/**
		 * 始终使用配置的区域设置
		 */
		FIXED,
		/**
		 * 使用“Accept Language”头或配置的区域设置(如果头未*设置)。
		 */
		ACCEPT_HEADER

	}

getLocale():也是一个属性,还是可以通过spring.web的yaml来修改的,呦西
很明确了,我们自己在yaml配置,就是在这里面配的属性了
可能你不信,localeResolver 看见没,就是上面贴出来的代码,就是这个类的
呀,就是说了可以自定义,修改了localeResolver ,我们就可以进if了,进了if就读修改的信息嘛
这里就是把locale改了一下(local:地区)

	public Locale getLocale() {
		return this.locale;
	}
@ConfigurationProperties("spring.web")
public class WebProperties {

	/**
		要使用的区域设置。默认情况下,此区域设置由“Accept Language”头覆盖。.
	 */
	private Locale locale;
    private LocaleResolver localeResolver = LocaleResolver.ACCEPT_HEADER;
}

this.mvcProperties.getLocaleResolver() :
tm的要不要长得这么像,mvc,web就算了,属性的也这么像
但是最后都一样,跟前面一样,只要不set一下localeResolver ,肯定是不相等的
卧槽,又不相等,扎回事,又是一个自定义??才能进去的?? 我才自定义了一次
我懂了,只要自定义了两个if都要进去

	@Deprecated
	@DeprecatedConfigurationProperty(replacement = "spring.web.locale-resolver")
	public LocaleResolver getLocaleResolver() {
		return this.localeResolver;
	}
@ConfigurationProperties(prefix = "spring.mvc")
public class WebMvcProperties {
	/**
	 * 要使用的区域设置。默认情况下,此区域设置由“Accept Language”*头覆盖。
	 */
	private Locale locale;

	/**
	 * 定义应如何解析区域设置。
	 */
	private LocaleResolver localeResolver = LocaleResolver.ACCEPT_HEADER;
}

	@Deprecated
	public enum LocaleResolver {
		FIXED,
		ACCEPT_HEADER
	}

总结:我可能骗了你们,这个看了我都总结不出什么东西

那假如我们现在想点击链接让我们的国际化资源生效,就需要让我们自己的Locale生效!

我们去自己写一个自己的LocaleResolver,可以在链接上携带区域信息!

修改一下前端页面的跳转连接:


<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')}">Englisha>
public class MyLocaleResolver implements LocaleResolver {
  //解析请求
  @Override
  public Locale resolveLocale(HttpServletRequest request) {
    String parameter = request.getParameter("l");
    Locale locale = Locale.getDefault();

    //如果请求链接不为空
    if (!StringUtils.isEmpty(parameter)) {
      //分割请求参数  识别分割的符号,可以设置其他的这里我设置-
      //就是分割zh-CN 分成zh CN;你写成zh+CN,这里就用+
      String[] strings = parameter.split("-");
      //国家,地区
      locale = new Locale(strings[0], strings[1]);
    }
    return locale;
  }

  @Override
  public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {

  }
}

为了让我们的区域化信息能够生效,我们需要再配置一下这个组件!在我们自己的MvcConofig下添加bean;

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
  //方法名字不要与返回的new 的名字一样
  @Bean
  public LocaleResolver localeResolver(){
    return new MyLocaleResolver();
  }

我们重启项目,来访问一下,发现点击按钮可以实现成功切换!搞定收工!

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号