目录
Internationalization 国际化
数据绑定(DataBinder)之属性值绑定(PropertyValues)
1.Internationnalization 国际化介绍
i18n是internationalization(国际化)的缩写。因为单词比较长,取首字母i和末字母n,中间还有18个 字母,所以叫做i18n。
国际化可以实现让同一个项目,在不同语言环境中显示不同语言文字。
就像我们人一样,在国内就说汉语,去美国就说英语
2.JDK中的国际化 ResourceBundle
2.1 ResourceBundle介绍
在JDK中提供ResourceBundle抽象类,可以实现国际化。类中有静态方法,可以通过getBundle()来通过 属性文件进行实例化。String类型参数时basename(文件基础名称)
ResourceBundle加载属性文件时,会根据服务器语言环境,来判断到底加载哪个属性文件。 允许我们有多个相同basename的属性文件,然后根据不同语言,不同国家来定义多个属性文件。
语法:basename_语言简写_国家简写.properties
语言简称:
zh 中文
en 英文
国家简称:
中国 CN
美国 US
2.2 修改IDEA配置
默认情况下IDEA中.properties文件使用ISO-8859-1编码,我们的程序是UTF-8编码,获取中文会乱码。 设置IDEA,使用JDK自带的native-to-ascii工具把文件内容进行转码为UTF-8
2.3 新建多个配置文件
在src/main/resouces中新建3个配置文件。 rb.properties
name=默认名字
age=默认年龄
remark=默认介绍
rb_en_US.properties
name=smallming
age=16
remark=smallming is handsome
rb_zh_CN.properties
name=张佳明
age=16岁
remark=张佳明是帅哥
2.4 测试效果
新建测试类com.tong.test.ResourceBundleTest
public class ResourceBundleTest {
@Test
void test() throws IOException {
// 第一个参数是属性文件的basename,不包含语言简称和国际简称的。
// 第二个参数可以省略。自动判断服务器语言环境。
// 如果第二个参数设定的国家不存在,使用服务器语言环境
// 如果第二个参数设定的国家存在,使用对应属性文件内容
ResourceBundle rb2 = ResourceBundle.getBundle("rb", Locale.US);
System.out.println(rb2.getString("name"));
System.out.println(rb2.getString("age"));
System.out.println(rb2.getString("remark"));
}
}
2.5 结合MessageFormat设置占位符值
修改rb_zh_CN.propeties文件,添加占位符。占位符语法 {索引}
name=张佳明
age=16岁
remark=张佳明是帅哥,首先因为:{0},其实因为:{1}
在测试类,使用MessageFormat对占位符设置值。
@Test
void test2() throws IOException {
ResourceBundle rb2 = ResourceBundle.getBundle("rb");
String remark = rb2.getString("remark");
System.out.println(remark);
String format = MessageFormat.format(remark, "帅", "还是帅");
System.out.println(format);
}
3.Spring框架中国际化
Spring中国际化是通过MessageSource进行实现的。MessageSource是对java.util.ResourceBundle的 上层封装。相对性能要比ResourceBundle有提升。
MessageSource接口提供了三个方法。
public interface MessageSource {
/*
code : 内容的key
args : 当内容的value中有占位符时,对占位符的填充
defaultMessage:查找失败的默认消息
locale: 时区,根据时区来选择使用哪个语言集
*/
@Nullable
String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale);
String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException;
String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;
}
MessageSource接口有三个常用专门做国际化的实现类(ClasspathXmlApplicationContext等也是实现类)。
ApplicationContext接口默认就实现了MessageSource接口。所以ApplicationContext所有实现类都包含国际化功能。
public interface ApplicationContext extends EnvironmentCapable,
ListableBeanFactory, HierarchicalBeanFactory,MessageSource, ApplicationEventPublisher, ResourcePatternResolver
3.1代码实现步骤
准备多个properties文件
可以使用上面的三个属性文件。
配置文件
新建一个配置文件applicationContext-messageSource.xml。 使用MessageSource的实现类ResourceBundleMessageSource。类中包含属性basename,用于设置加载属性文件的基础名称。
Bean的id必须叫做messageSource,因为在ClassPathXmlApplicationContext的祖先类 AbstractApplicationContext中包含全局属性messageSource,如果名称不对应,无法进行注入。
新建测试类
新建com.tong.test.MessageResourceTest。 注入MessageSource后,获取消息。 可以发现,如果Locale对应的国家信息不存在,还是使用服务器的语言编码进行识别。
@SpringJUnitConfig
@ContextConfiguration("classpath:applicationContext-messageSource.xml")
public class MessageResourceTest {
@Autowired
MessageSource messageSource;
@Test
void test(){
String remark = messageSource.getMessage("remark", new String[]{"帅", "还是帅"},Locale.CHINA);
System.out.println(remark);
}
}
1.数据绑定 DataBinder
数据绑定DataBinder是Spring框架核心功能之一。但是数据绑定功能属于底层功能,很多程序员在学习 Spring框架,甚至用了几年Spring框架都没有使用过。但是想要真正的了解透Spring框架,深入Spring 框架底层原理,数据绑定功能确是必学知识点之一。 Spring框架中数据绑定分为三个具体功能
我们将分为三个小章节分别来讲解这三个具体功能,这三个功能讲解完成,数据绑定就讲解完成了。
2.属性值绑定
Spring框架DataBinder中属性值绑定主要的两个具体应用场景:
1、XML配置时,Bean属性值绑定。解析完XML文件中Bean标签的属性值后,把值通过数据绑定到对 应属性。通过学习属性绑定可以清楚的知道,Spring框架底层到底如何运行的,这也是为什么要讲 属性绑定的原因之一。
2、Spring MVC时接收HTTP参数,绑定到控制单元方法参数(SpringMVC框架的知识点)
Bean属性值绑定底层使用PropertyValues接口进行实现。接口实现了Iterable接口
public interface PropertyValues extends Iterable
里面提供了几个方法。
接口只有一个实现类
public class MutablePropertyValues implements PropertyValues, Serializable
MutablePropertyValues里面提供了有参构造方法,在实例化时直接进行数据绑定。
也可以实例化后,使用addPropertyValue添加一个属性值
也可以实例化后,使用addPropertyValues添加多个属性值。
3.使用Map进行数据绑定
数据绑定时,要保证属性名和Map的Key对应。Map中Value值类型不用必须和类属性类型对应。类型转 换可以由Spring框架完成。
@Test
void testPropertyValue(){
People peo= new People();
Map map = new HashMap<>();
map.put("id","1");
map.put("name","smallming");
PropertyValues pv =new MutablePropertyValues(map);
DataBinder dataBinder = new DataBinder(peo,"people");
dataBinder.bind(pv);
System.out.println(peo);
}
4.使用PropertyValue进行数据绑定
org.springframework.beans.PropertyValue 是Spring框架对Bean属性的抽象类。一个PropertyValue 对应Bean中一个属性。所以我们可以看到MutablePropertyValues有参构造方法参数是List
public MutablePropertyValues(@Nullable List propertyValueList)
PropertyValue使用起来也很简单,通过构造方法,可以直接设定属性名及值是什么。
public PropertyValue(String name, @Nullable Object value)
所以当使用PropertyValue进行数据绑定时的代码和上面使用Map进行数据绑定的代码,就把Map换成了 List
@Test
void testPropertyValue(){
People peo= new People();
List list = new ArrayList<>();
list.add(new PropertyValue("id","2"));
list.add(new PropertyValue("name","smallming"));
PropertyValues pv =new MutablePropertyValues(list);
DataBinder dataBinder = new DataBinder(peo,"people");
dataBinder.bind(pv);
System.out.println(peo);
}