OGNL的概念,这里就不多介绍了。
我这里想做的就是通过一个ognl的简单的例子,我自己写一个程序,模拟ognl的信息获取。
信息存取的话,道理是一样的,这里读者自己可以参照我的代码实现数据存入。
我这里只讲OGNL的简单的链式获取,不涉及复杂的表达式部分,OGNL的NB之处在于表达式。
下面我们引入正题。看我下面的例子。
我们这里用OGNL获取Bean的信息,包括ArrayList,HashMap,以及数据对象。
下面贴代码了。
UserBean.java
import java.util.HashMap; import java.util.List; public class UserBean { private String userName=""; private long age=0L; private List list=null; //演示List private HashMap map =null; //演示MAP private UserAddrBean [] userAddr=null;//演示数组 public HashMap getMap() { return map; } public void setMap(HashMap map) { this.map = map; } public UserAddrBean[] getUserAddr() { return userAddr; } public void setUserAddr(UserAddrBean[] userAddr) { this.userAddr = userAddr; } public long getAge() { return age; } public void setAge(long age) { this.age = age; } public List getList() { return list; } public void setList(List list) { this.list = list; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } }
UserAddrBean.java
public class UserAddrBean { private String userName=""; private String addr1=""; private String addr2=""; public String getAddr1() { return addr1; } public void setAddr1(String addr1) { this.addr1 = addr1; } public String getAddr2() { return addr2; } public void setAddr2(String addr2) { this.addr2 = addr2; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } }
测试main函数
public static void main(String[] args) throws OgnlException { List list = new ArrayList(); list.add("list1"); list.add("list2"); list.add("list3"); UserBean user = new UserBean(); user.setAge(20000L); user.setList(list); user.setUserName("keyboardsun"); OgnlContext context1 = new OgnlContext(); HashMap map = new HashMap(); map.put("key", "value"); UserAddrBean [] bean = new UserAddrBean[2]; bean[0]= new UserAddrBean(); bean[0].setAddr1("addr1"); bean[1]=new UserAddrBean(); bean[1].setAddr2("addr2"); user.setUserAddr(bean); user.setMap(map); context1.put("user", user); Ognl.setValue("userName", user, "dev"); System.out.println(Ognl.getValue("userAddr[0].addr1", user)); System.out.println(Ognl.getValue("list[0]", user)); System.out.println(Ognl.getValue("userName", user)); System.out.println(Ognl.getValue(Ognl.parseExpression("user.userAddr[1].addr1"), context1)); System.out.println(Ognl.getValue(Ognl.parseExpression("user.list[1]"), context1)); System.out.println(Ognl.getValue(Ognl.parseExpression("user.userAddr[0].addr2"), context1)); System.out.println(Ognl.getValue(Ognl.parseExpression("user.userAddr[0].addr1"), context1)); System.out.println(Ognl.getValue(Ognl.parseExpression("user.map['key']"), context1)); System.out.println(Ognl.getValue(Ognl.parseExpression("user.userName"), context1)); }
运行输出结果是
addr1
list1
dev
list2
addr1
value
dev
菜鸟们可能觉得OGNL好神奇噢,我也这么觉得,是挺有想法的一个东东。搞的跟模板工具的获取方式很像。的确在数据对象的解耦合方面做了一个进步。
下面我们模拟开发一个这样的东东。功能与之类似。代码如下:
MyContext.java
import java.util.HashMap; public class MyContext extends HashMap { //就是一个壳子,大家别骂我,呵呵,MyContext就是一个map,以后根据需要,可以扩展这里的方法嘛,目前只是个壳子,有点虚伪的感觉 }
下面才是核心部分,bean表达式转换器噢。
这里的代码如果小菜鸟没有用过发射啥的东东,那就要多多研究研究了,这里用的东西个人觉得还是蛮有正对性的。
ValueEngine.java
import java.lang.reflect.Array; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import ognl.Ognl; import ognl.OgnlContext; import ognl.UserAddrBean; import ognl.UserBean; public class ValueEngine { public static Object getValue(String express,MyContext context) throws Exception{ if(express==null||express.equals("")) throw new NullPointerException("我靠,表达式也能为空??"); String [] exp = express.split("\\."); if(exp.length==1){ return context.get(express); } else { Object o= context.get(exp[0]); int i=1; while(exp.length!=i) { if(exp[i].indexOf("[")>0){ String md = "get"+exp[i].substring(0,1).toUpperCase()+exp[i].substring(1,exp[i].indexOf("[")); Method m = o.getClass().getMethod(md, new Class[]{}); o = m.invoke(o,new Object[]{}); if(o instanceof List) { int j = Integer.parseInt( exp[i].split("\\[")[1].split("\\]")[0]); o = ((List)o).get(j); } else if(o.getClass().getName().indexOf("[L")==0||o.getClass().isArray()){ int j = Integer.parseInt( exp[i].split("\\[")[1].split("\\]")[0]); o = Array.get(o, j); } else if(o instanceof Map){ String key = exp[i].split("'")[1]; o = ((Map)o).get(key); } } else { String md = "get"+exp[i].substring(0,1).toUpperCase()+exp[i].substring(1); Method m = o.getClass().getMethod(md, new Class[]{}); o = m.invoke(o,new Object[]{}); } i++; } return o; } } public static Object getValue(String express,Object context){ String [] exp = express.split("."); return null; } }
下面我们要模拟上面刚才运行的那个main函数了噢,呵呵。
不过这次的main函数,用的对象获取的方法是我刚写的方法。
运行main函数。试试效果,看看是不是跟OGNL的感觉一样
public static void main(String args[]) throws Exception{ MyContext c = new MyContext(); List list = new ArrayList(); list.add("list1"); list.add("list2"); list.add("list3"); UserBean user = new UserBean(); user.setAge(20000L); user.setList(list); user.setUserName("keyboardsun"); HashMap map = new HashMap(); map.put("key", "value"); UserAddrBean [] bean = new UserAddrBean[2]; bean[0]= new UserAddrBean(); bean[0].setAddr1("addr1"); bean[1]=new UserAddrBean(); bean[1].setAddr2("addr2"); user.setUserAddr(bean); user.setMap(map); c.put("user", user); System.out.println(ValueEngine.getValue("user.userAddr[0].addr1",c)); System.out.println(ValueEngine.getValue("user.list[0]",c)); System.out.println(ValueEngine.getValue("user.age",c)); System.out.println(ValueEngine.getValue("user.map['key']",c)); System.out.println(ValueEngine.getValue("user.userAddr[1].addr1",c)); System.out.println(ValueEngine.getValue("user.list[1]",c)); System.out.println(ValueEngine.getValue("user.userAddr[0].addr2",c)); System.out.println(ValueEngine.getValue("user.userAddr[0].addr1",c)); System.out.println(ValueEngine.getValue("user.map['key']",c)); System.out.println(ValueEngine.getValue("user.userName",c)); }
输出是:
addr1
list1
20000
value
list2
addr1
value
keyboardsun
你看看,是不是和ognl的效果一样啊,是不是很神奇呢。我这里只是模拟,核心的意思跟ognl差不多。
供大家玩玩参考使用,别以为ognl有多神奇,我们要善于去把握其中的原理。当然,我这里演示的只是OGNL最简单的一角,它的强大之处可不在这里,所以大家别简单的认为ognl不过如此。其实ognl很强大,尤其是表达式部分。
Ognl的源码我没有细看,大概的简单数据获取原理就是这样的,你看看,我上面就10来行的代码,就可以实现这么好的功能了噢,菜鸟们多学习学习吧。
作者 keyboardsun
转载请表明出处噢。