OGNL表达式与国际化
-掌握国际化的应用
-熟练掌握OGNL的结构
-熟练掌握OGNL在Struts中的使用方式
国际化
在web项目中,国际化就是web项目支持多国语言,适应当地人的语言要求。比如,新浪微博里就有中文和英文,但新浪微博有一定的人力财力,采用英汉单独分开写的方式。
一般在构建Struts项目时,可以采用Struts提供的国际化进行项目的开发。
国际化的定义:
国际化(internationalization)又称为i18N,是设计和制造适应不同区域要求的产品的一种方式,是抹平国家和地区差异化的过程。
国际化的实现思路:
转备好多个语言版本的资源文件
根据当地系统语言决定调用哪个资源文件
读取对应的资源文件并呈现
Locale对象
Locale对象封装了语言地区的相关信息
getCounrty获取国家代码
getLanguage获取语言代码
//获取当前的Locale信息
Locale locale = Locale.getDefault(); System.out.println(locale.getCountry()+"\t"+locale.getLanguage());
- CN zh
资源文件的要求
文件名_语言代码_国家代码.properties
resource_zh_CN.properties 中文要进行编码
resource_en_US.properties
name=\u7528\u6237\u540D
pwd=\u5BC6\u7801\u54C8\u54C8
name=userName
pwd=password
资源文件调用范围
全局资源文件
包级资源文件
类级资源文件
全局资源文件
可以在这个项目中共享资源文件,最常用的方式,需要在struts.xml配置constant属性
<!-- 配置国际化的工具对象 -->
<constant name="struts.custom.i18n.resources" value="resource"></constant>
包级资源文件
只能在当前包中共享资源文件信息
命名规则:package_语言代码_国家代码.properties
类级资源文件
只能在当前类中访问资源文件信息
命名规则:ActionName_语言代码_国家代码.properties
资源信息的访问
在JSP页面通过
<s:text name="key">标签访问
<form action="login.action" method="post">
<s:text name="name">:</s:text><input name="userName"><br/>
<s:text name="pwd">:</s:text> <input type="password" name="password"><br/>
<input type="submit" value="Login">
</form>
Action通过getText方法访问
getText(String key)
getText(String key,list args)
OGNL
在JSP中,我们之前通过EL表达式进行服务端数据的呈现
在Struts中,我们又可以使用OGNL表达式进行服务端数据的呈现,并且OGNL的功能远远大于EL表达式的,同时我们也可以两者结合使用。
接下来我们先介绍下什么是OGNL?
OGNL(Object-Graph Navigation Language)是一种使用灵活的表达式语言,可以存取对象的任意属性,调用对象的方法,遍历对象的整个结构图,实现字段类型的转换等。它使用相同的表达式存取对象的属性。
EL和OGNL的区别
常规OGNL通过根对象访问对象的属性和方法。
Root对象可以由多个对象构成,Context对象只有一个。
通常我们把常用的对象信息写入Context对象中,便于多次访问。
例:
Foo类结构 该类属性有Integer类型,String类型,List集合,Map集合,对象类型等等,提供setter和getter方法
public class Foo {
private Integer id;
private String name;
private String[] array;
private List<String> list;
private Map<String, String> map;
private User user;
private List<User> userList;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String[] getArray() {
return array;
}
public void setArray(String[] array) {
this.array = array;
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
public Map<String, String> getMap() {
return map;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public List<User> getUserList() {
return userList;
}
public void setUserList(List<User> userList) {
this.userList = userList;
}
}
初始化Foo对象
//初始化Foo对象
Foo foo = new Foo();
foo.setId(1001);
foo.setName("tom");
String[] array = new String[]{"a","b","c"};
foo.setArray(array);
List<String> list = Arrays.asList("A","B","C");
foo.setList(list);
Map<String, String> map = new HashMap<String, String>();
map.put("keyA", "valueA");
map.put("keyB", "valueB");
map.put("keyC", "valueC");
foo.setMap(map);
User user = new User();
user.setUserName("jack");
user.setPassword("jack123");
foo.setUser(user);
List<User> userList = Arrays.asList(new User("userA", "111"),new User("userB", "222"), new User("userC", "333"));
foo.setUserList(userList);
使用原生的OGNL表达式访问数据
OGNL本质就是一套对象反射的工具
Object value;
value = Ognl.getValue("id", foo);
value = Ognl.getValue("userName", user);
(2)访问引用数据类型
value = Ognl.getValue("user.password", foo);
(3)访问数组或list集合
value = Ognl.getValue("array[0]", foo);
value = Ognl.getValue("list[1]", foo);
value = Ognl.getValue("userList[0].userName", foo);
(4)访问map集合
value = Ognl.getValue("map.keyC", foo);
(5)运算
value = Ognl.getValue("id+1", foo);
value = Ognl.getValue("id+name", foo);
value = Ognl.getValue("name=='tom'", foo);
(6)调用方法
value = Ognl.getValue("name.length()", foo);
value = Ognl.getValue("list.indexOf(\"B\")", foo);
(7)创建集合
value = Ognl.getValue("{'a','b','c'}", null);
value = Ognl.getValue("#{'a':'A','b':'B'}", null);
System.out.println(value.getClass());
第一个是ArrayList
第二个是LinkedHashMap
在Context中访问数据
Context必须是map集合
初始化:
Map<String, Object> context = new HashMap<String, Object>();
context.put("name", "tony");
context.put("user", new User("lucy", "112233"));
context.put("actionName", "loginAction");
context.put("foo", foo);
第一个参数表示获取数据的表达式,第二个参数是获取数据的上下文对象,第三个参数表示root对象
默认情况下,表达式直接获取root对象的数据,所以我们需要通过
# 来访问上下文的数据
value = Ognl.getValue("#actionName", context, foo);
//表示获取foo对象中user属性的userName
value = Ognl.getValue("user.userName", context, foo);
//表示获取contxt中键为user的对象的属性userName
value = Ognl.getValue("#user.userName", context, foo);
Struts2中对OGNL进行了相应的改动,主要体现在将多个root对象封装成valueStack对象,该对象为栈结构,请求的对象将会被存入栈顶,请求结束后将对象从栈顶移除,并且提供request、session、application、parameters这五个与valueStack并级的对象。
在Struts2中,OGNL访问的context是ActionContext对象,位于ActionContext中的root对象是valueStack,
request、session、application、parameters是属于context中的子节点。
Strust2的OGNL的使用
Struts2的OGNL需要结合struts2标签来使用,主要通过
# 直接访问根上下文中的对象
$ 资源文件或配置文件中访问OGNL
% 将字符串作为OGNL表达式进行计算