资源文件与国际化

/ Java SE / 0 条评论 / 2780浏览

为了方便学习java api(其实是我老是记不住文档地址o(╥﹏╥)o),于是我将最新的jdk8的api文档放到了自己服务器上,同时也可以方便大家学习哦~

在平时使用Spring或者SpringBoot是,都会使用一个叫xxx.yml或者xxx.properties的配置文件,大部分框架配置都是在其中进行的,对于这些框架是怎么读取到这些文件的配置的,困扰我来很久,虽然我知道他们可以使用@Value注解来获取,但是底层如何实现的仍然是我想搞明白的,后来看了一些视频才知道这些配置文件属于Java中资源文件的范畴,于是今天简单地学了一下资源文件以及国际化处理。

资源文件

所谓的资源文件指的是后缀名称为“*.properties”里面保存的内容按照“key=value”的形式保存,而且资源文件的命名标准与Java类的命名标准一致。

示例:建一个Config.properties(放在src目录下,此目录是CLASSPATH目录)

site=www.beifeng.com
name=北风tz
introduction=大家好!我是{0},欢迎来到{1}
site=www.beifeng.com
name=\u5317\u98cetz
introduction=\u5927\u5bb6\u597d\uff01\u6211\u662f{0}\uff0c\u6b22\u8fce\u6765\u5230{1}

这里的site和name是保存的key,后面的是value。不过需要注意到的一点是虽然我们在编辑器中写入中文后看到的是正常的(我用的idea),但是实际上java能读取的并不是中文,如果有中文一定是读取的Unicode编码后的字串!!!在资源文件中是不允许存在中文的,在spring框架中之所以我们会看到是因为在框架内部已经帮我们Unicode编码转换过来了,yml文件也是一样。

YAML(Yet Another Markup Language)(发音 /ˈjæməl/ ) 一种基于Unicode容易阅读,容易和脚本语言交互的,用来表达资料序列的编程语言。

如果要读取资源文件的信息,需要使用java.util.ResourceBundle类,这是一个抽象类,类中提供了一个static方法可以获取本类对象:

在第二个方法中设计到Local对象,这个类是一个本地化的工具类,后面介绍。

package language;

import java.util.ResourceBundle;

/**
 * @Author beifengtz
 * @Site www.beifengtz.com
 * @Date Created in 20:43 2019/1/22
 * @Description:
 */
public class ResourceTest {

    public static void main(String[] args) {
        // 访问时不需要加后缀,因为默认找到的后缀就是“*.properties”
        // 此时的Config.properties文件一定要放在CLASSPATH路径下
        ResourceBundle resourceBundle = ResourceBundle.getBundle("Config");
        System.out.println(resourceBundle);
    }
}

当获取了ResourceBundle类之后可以通过下面的方法进行读取数据:

package language;

import java.text.MessageFormat;
import java.util.ResourceBundle;

/**
 * @Author beifengtz
 * @Site www.beifengtz.com
 * @Date Created in 20:43 2019/1/22
 * @Description:
 */
public class ResourceTest {

    public static void main(String[] args) {
        // 访问时不需要加后缀,因为默认找到的后缀就是“*.properties”
        // 此时的Config.properties文件一定要放在CLASSPATH路径下
        ResourceBundle resourceBundle = ResourceBundle.getBundle("Config");
        String site = resourceBundle.getString("site");
        String name = resourceBundle.getString("name");
        String introductionA = resourceBundle.getString("introduction"); // 直接读取
        String introductionB = resourceBundle.getString("introduction");
        System.out.println(site);
        System.out.println(name);
        System.out.println("直接读取:"+introductionA);
        System.out.println("传入占位符值:"+ MessageFormat.format(introductionB,name,"北风个人博客"));
    }
}

运行结果:

www.beifeng.com
北风tz
直接读取:大家好!我是{0},欢迎来到{1}
传入占位符值:大家好!我是北风tz,欢迎来到北风个人博客

国际化

国际化程序应该要根据所在的国家不同可以显示不同的内容,可是如果只有一个资源文件是不能进行不同语言的显示的。一般的国际化程序都是一套程序不同的资源包,因为在不同的国家或地区,这套程序的功能始终不变,而唯一可能变化的就是语言的不同。所有要想实现国际化,就需要进一步了解Local类了,Local保存的是一个国家的区域和语言编码。

下面是常见的几个国家的语言编码:

我们要实现不同语言的资源文件只需要在文件后面加上语言后缀即可,在调用的时候也不需要附带后缀,例如:

Config_zh_CN.properties

site=www.beifeng.com
name=\u5317\u98cetz
introduction=\u5927\u5bb6\u597d\uff01\u6211\u662f{0}\uff0c\u6b22\u8fce\u6765\u5230{1}

Config_en_US.properties

site=www.beifeng.com
name=beifengtz
introduction=Hello !I'm {0}. Welcome to {1}

测试代码:

package language;

import java.text.MessageFormat;
import java.util.Locale;
import java.util.ResourceBundle;

/**
 * @Author beifengtz
 * @Site www.beifengtz.com
 * @Date Created in 20:43 2019/1/22
 * @Description:
 */
public class ResourceTest {

    public static void main(String[] args) {
        // 访问时不需要加后缀,因为默认找到的后缀就是“*.properties”
        // 此时的Config.properties文件一定要放在CLASSPATH路径下
        ResourceBundle resourceBundle = ResourceBundle.getBundle("Config");
        String site = resourceBundle.getString("site");
        String name = resourceBundle.getString("name");
        String introductionA = resourceBundle.getString("introduction"); // 直接读取
        String introductionB = resourceBundle.getString("introduction");
        System.out.println(site);
        System.out.println(name);
        System.out.println("直接读取:"+introductionA);
        System.out.println("传入占位符值:"+ MessageFormat.format(introductionB,name,"北风个人博客"));

        // 获取默认的语言编码
        System.out.println(Locale.getDefault());
    }
}

输出:

www.beifeng.com
北风tz
直接读取:大家好!我是{0},欢迎来到{1}
传入占位符值:大家好!我是北风tz,欢迎来到北风个人博客
zh_CN

因为我的电脑地区语言是设置的中国,所以它自动获取了Config_zh_CN.properties文件的内容,如果想手动获取其他语言环境的文件,需要传入Locale对象

package language;

import java.text.MessageFormat;
import java.util.Locale;
import java.util.ResourceBundle;

/**
 * @Author beifengtz
 * @Site www.beifengtz.com
 * @Date Created in 20:43 2019/1/22
 * @Description:
 */
public class ResourceTest {

    public static void main(String[] args) {
        Locale locale = new Locale("en","US");
        // 访问时不需要加后缀,因为默认找到的后缀就是“*.properties”
        // 此时的Config.properties文件一定要放在CLASSPATH路径下
        ResourceBundle resourceBundle = ResourceBundle.getBundle("Config",locale);
        String site = resourceBundle.getString("site");
        String name = resourceBundle.getString("name");
        String introductionA = resourceBundle.getString("introduction"); // 直接读取
        String introductionB = resourceBundle.getString("introduction");
        System.out.println(site);
        System.out.println(name);
        System.out.println("直接读取:"+introductionA);
        System.out.println("传入占位符值:"+ MessageFormat.format(introductionB,name,"北风个人博客"));

        // 获取默认的语言编码
        System.out.println(Locale.getDefault());
    }
}

运行结果:

www.beifeng.com
beifengtz
直接读取:Hello !I'm {0}. Welcome to {1}
传入占位符值:Hello !Im {0}. Welcome to {1}
zh_CN

这个时候获取的内容就是Config_en_US.properties的内容了。

ResourceBundle类查找Properties的顺序如下:

微信公众号浏览体验更佳,在这里还有更多优秀文章为你奉上,快来关注吧!

北风IT之路