面试不易,控场情况下,感觉少要了1万

  1. 国际化如何处理资源文件变化的问题?

  2. 国际化资源配置放在db中如何实现?

先说一下什么是国际化


简单理解,就是对于不同的语言,做出不同的响应。

比如页面中有个填写用户信息的表单,有个姓名的输入框

浏览器中可以选择语言

选中文的时候会显示:

姓名:一个输入框

选英文的时候会显示:

Full name:一个输入框

国际化就是做这个事情的,根据不同的语言显示不同的信息。

所以需要支持国际化,得先知道选择的是哪种地区的哪种语言,java中使用java.util.Locale来表示地区语言这个对象,内部包含了国家和语言的信息。

Locale中有个比较常用的构造方法

public Locale(String language, String country) {

this(language, country, “”);

}

2个参数:

language:语言

country:国家

语言和国家这两个参数的值不是乱写的,国际上有统一的标准:

比如language的值:zh表示中文,en表示英语,而中文可能很多地区在用,比如大陆地区可以用:CN,新加坡用:SG;英语也是有很多国家用的,GB表示英国,CA表示加拿大

国家语言简写格式:language-country,如:zh-CN(中文【中国】),zh-SG(中文【新加坡】),en-GB(英语【英国】),

en-CA(英语【加拿大】)。

还有很多,这里就不细说了,国家语言编码给大家提供一个表格:http://www.itsoku.com/article/282

Locale类中已经创建好了很多常用的Locale对象,直接可以拿过来用,随便列几个看一下:

static public final Locale SIMPLIFIED_CHINESE = createConstant(“zh”, “CN”); //zh_CN

static public final Locale UK = createConstant(“en”, “GB”); //en_GB

static public final Locale US = createConstant(“en”, “US”); //en_US

static public final Locale CANADA = createConstant(“en”, “CA”); //en_CA

再回头看前面的问题:页面中显示姓名对应的标签,需要我们根据一个key及Locale信息来获取对应的国际化信息,spring中提供了这部分的实现,下面我们来看详情。

Spring中国际化怎么用?


MessageSource接口

spring中国际化是通过MessageSource这个接口来支持的

org.springframework.context.MessageSource

内部有3个常用的方法用来获取国际化信息,来看一下

public interface MessageSource {

/**

* 获取国际化信息

* @param code 表示国际化资源中的属性名;

* @param args用于传递格式化串占位符所用的运行参数;

* @param defaultMessage 当在资源找不到对应属性名时,返回defaultMessage参数所指定的默认信息;

* @param locale 表示本地化对象

*/

@Nullable

String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale);

/**

* 与上面的方法类似,只不过在找不到资源中对应的属性名时,直接抛出NoSuchMessageException异常

*/

String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException;

/**

* @param MessageSourceResolvable 将属性名、参数数组以及默认信息封装起来,它的功能和第一个方法相同

*/

String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;

}

常见3个实现类

ResourceBundleMessageSource

这个是基于Java的ResourceBundle基础类实现,允许仅通过资源名加载国际化资源

ReloadableResourceBundleMessageSource

这个功能和第一个类的功能类似,多了定时刷新功能,允许在不重启系统的情况下,更新资源的信息

StaticMessageSource

它允许通过编程的方式提供国际化信息,一会我们可以通过这个来实现db中存储国际化信息的功能。

Spring中使用国际化的3个步骤


通常我们使用spring的时候,都会使用带有ApplicationContext字样的spring容器,这些容器一般是继承了AbstractApplicationContext接口,而这个接口实现了上面说的国际化接口MessageSource,所以通常我们用到的ApplicationContext类型的容器都自带了国际化的功能。

通常我们在ApplicationContext类型的容器中使用国际化3个步骤

步骤一:创建国际化文件

步骤二:向容器中注册一个MessageSource类型的bean,bean名称必须为:messageSource

步骤三:调用AbstractApplicationContext中的getMessage来获取国际化信息,其内部将交给第二步中注册的messageSource名称的bean进行处理

来个案例感受一下

创建国际化文件

国际化文件命名格式:名称_语言_地区.properties

我们来3个文件,文件都放在下面这个目录中

com/javacode2018/lesson002/demo19/

message.properties

name=您的姓名

personal_introduction=默认个人介绍:{0},{1}

这个文件名称没有指定Local信息,当系统找不到的时候会使用这个默认的

message_zh_CN.properties:中文【中国】

name=姓名

personal_introduction=个人介绍:{0},{1},{0}

message_en_GB.properties:英文【英国】

name=Full name

personal_introduction=personal_introduction:{0},{1},{0}

spring中注册国际化的bean

注意必须是MessageSource类型的,bean名称必须为messageSource,此处我们就使用ResourceBundleMessageSource这个类

package com.javacode2018.lesson002.test19.demo1;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.support.ResourceBundleMessageSource;

@Configuration

public class MainConfig1 {

@Bean

public ResourceBundleMessageSource messageSource() {

ResourceBundleMessageSource result = new ResourceBundleMessageSource();

//可以指定国际化化配置文件的位置,格式:路径/文件名称,注意不包含【语言_国家.properties】含这部分

result.setBasenames(“com/javacode2018/lesson002/demo19/message”); //@1

return result;

}

}

@1:这个地方的写法需要注意,可以指定国际化化配置文件的位置,格式:路径/文件名称,注意不包含**【语言_国家.properties】**含这部分

来个测试用例

package com.javacode2018.lesson002.test19;

import com.javacode2018.lesson002.test19.demo1.MainConfig1;

import org.junit.Test;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import java.util.Locale;

public class MessageSourceTest {

@Test

public void test1() {

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();

context.register(MainConfig1.class);

context.refresh();

//未指定Locale,此时系统会取默认的locale对象,本地默认的值中文【中国】,即:zh_CN

System.out.println(context.getMessage(“name”, null, null));

System.out.println(context.getMessage(“name”, null, Locale.CHINA)); //CHINA对应:zh_CN

System.out.println(context.getMessage(“name”, null, Locale.UK)); //UK对应en_GB

}

}

运行输出

您的姓名

您的姓名

Full name

第一行未指定Locale,此时系统会取默认的locale对象,本地默认的值中文【中国】,即:zh_CN,所以会获取到message_zh_CN.properties中的内容。

后面2行,都指定了Locale对象,找到对应的国际化文件,取值。

动态参数使用

注意配置文件中的personal_introduction,个人介绍,比较特别,包含了{0},{1},{0}这样一部分内容,这个就是动态参数,调用getMessage的时候,通过第二个参数传递过去,来看一下用法:

@Test

public void test2() {

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();

context.register(MainConfig1.class);

context.refresh();

//未指定Locale,此时系统会取默认的,本地电脑默认的值中文【中国】,即:zh_CN

System.out.println(context.getMessage(“personal_introduction”, new String[]{“spring高手”, “java高手”}, Locale.CHINA)); //CHINA对应:zh_CN

System.out.println(context.getMessage(“personal_introduction”, new String[]{“spring”, “java”}, Locale.UK)); //UK对应en_GB

}

运行输出

默认个人介绍:spring高手,java高手

personal_introduction:spring,java,spring

监控国际化文件的变化


ReloadableResourceBundleMessageSource这个类,功能和上面案例中的ResourceBundleMessageSource类似,不过多了个可以监控国际化资源文件变化的功能,有个方法用来设置缓存时间:

public void setCacheMillis(long cacheMillis)

-1:表示永远缓存

0:每次获取国际化信息的时候,都会重新读取国际化文件

大于0:上次读取配置文件的时间距离当前时间超过了这个时间,重新读取国际化文件

还有个按秒设置缓存时间的方法setCacheSeconds,和setCacheMillis类似

下面我们来案例

package com.javacode2018.lesson002.test19.demo2;

import org.springframework.context.MessageSource;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.support.ReloadableResourceBundleMessageSource;

@Configuration

public class MainConfig2 {

@Bean

public MessageSource messageSource() {

ReloadableResourceBundleMessageSource result = new ReloadableResourceBundleMessageSource();

result.setBasenames(“com/javacode2018/lesson002/demo19/message”);

//设置缓存时间1000毫秒

result.setCacheMillis(1000);

return result;

}

}

message_zh_CN.properties中新增一行内容

address=上海

对应的测试用例

@Test

public void test3() throws InterruptedException {

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();

context.register(MainConfig2.class);

context.refresh();

//输出2次

for (int i = 0; i < 2; i++) {

System.out.println(context.getMessage(“address”, null, Locale.CHINA));

TimeUnit.SECONDS.sleep(5);

}

}

上面有个循环,当第一次输出之后,修改一下message_zh_CN.properties中的address为上海松江,最后运行结果如下:

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
img

最后

在面试前我整理归纳了一些面试学习资料,文中结合我的朋友同学面试美团滴滴这类大厂的资料及案例

MyBatis答案解析
由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!

大家看完有什么不懂的可以在下方留言讨论也可以关注。

觉得文章对你有帮助的话记得关注我点个赞支持一下!

中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-my6ig9gd-1710438248686)]
[外链图片转存中…(img-iB7Rsiti-1710438248687)]
[外链图片转存中…(img-KWcVa9zp-1710438248687)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
[外链图片转存中…(img-Hhy9T3r1-1710438248688)]

最后

在面试前我整理归纳了一些面试学习资料,文中结合我的朋友同学面试美团滴滴这类大厂的资料及案例
[外链图片转存中…(img-uxin1NuG-1710438248688)]

[外链图片转存中…(img-5u1QtP6Z-1710438248689)]
由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!

大家看完有什么不懂的可以在下方留言讨论也可以关注。

觉得文章对你有帮助的话记得关注我点个赞支持一下!

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值