当前位置: 首页 > 工具软件 > OGNL > 使用案例 >

OGNL的使用

秦奇
2023-12-01

OGNL 可以通过表达式从java对象中获取值或向java对象赋值。

Ognl.java 源码:

    参数说明:

  expression :Strig对象,

            表达式 指明对root或context中的哪个属性或方法操作 (set or get or call)

Object root :任意一个java对象

            从中取值或赋值,不以#开头的表达式,是对root取值或赋值

 context :一个Map对象,

          1.可以从中取值 以#开头的表达式是从context取值

          2. 含Ognl的上下文对象(见addDefaultContext方法)

  tree:一个Node对象

           是Ognl.parseExpression(expression) 而生成的对象,即对表达式解析之后的对象            

  resultType:一个Class对象

         期望的返回值类型,需要对获取的结果类型转换,

  

1.生成一个context (上下文对象)

/** 
 Ognl中有多个addDefaultContext方法,都是用来生成 context的 
context 结构: 
a.key=OgnlContext.CLASS_RESOLVER_CONTEXT_KEY,对应的是ClassResolver对象:自定义的加    载类,Ognl有默认的ClassResolver,如果ClassResolver不能加载类,就需要自定义的加载类。 
b.key=OgnlContext.TYPE_CONVERTER_CONTEXT_KEY,对应的是TypeConverter对象:自定义类型   转换,Ognl有默认的类型转换TypeConverter,如果默认的转换不了,就需要指定自定义转换器 
c.key=OgnlContext.MEMBER_ACCESS_CONTEXT_KEY,对应的是MemberAccess对象 
d.key=OgnlContext.ROOT_CONTEXT_KEY,对应的是Root对象==参数root,getValue或                                           setValue方法中会把root保存在context中。 
**/  
public static Map addDefaultContext(Object root, ClassResolver classResolver,  
                                        TypeConverter converter, MemberAccess memberAccess, Map context)  
    {  
        OgnlContext result;  
  
        if (!(context instanceof OgnlContext)) {  
            result = new OgnlContext();  
            result.setValues(context);  
        } else {  
            result = (OgnlContext) context;  
        }  
        if (classResolver != null) {  
            result.setClassResolver(classResolver);  
        }  
        if (converter != null) {  
            result.setTypeConverter(converter);  
        }  
        if (memberAccess != null) {  
            result.setMemberAccess(memberAccess);  
        }  
  
        result.setRoot(root);  
        return result;  
    }  

2.获取值:

/** 
* Ognl有多个重载的getValue: 
*getValue(String expression, Object root) 
*getValue(String expression, Object root, Class resultType) 
*getValue(Object tree, Object root, Class resultType) 
*getValue(Object tree, Map context, Object root) 
*getValue(String expression, Map context, Object root) 
*getValue(String expression, Map context, Object root, Class resultType) 
* 最终都调用下面这个方法 
*  参数:<span style="font-family: Helvetica, Tahoma, Arial, sans-serif; white-space: normal; background-color: #ffffff;"> 
*               tree 由对表达式解析(Ognl.parseExpression(expression))而生成的对象 
*               context:上下文 
</span>*       root: 要操作的java对象 
*       resultType:结果要转换成为的类型    
**/  
public static Object getValue(Object tree, Map context, Object root, Class resultType)  
            throws OgnlException  
    {  
        Object result;  
        OgnlContext ognlContext = (OgnlContext) addDefaultContext(root, context);  
  
        Node node = (Node)tree;  
  
        if (node.getAccessor() != null)  
            result =  node.getAccessor().get(ognlContext, root);  
        else  
            result = node.getValue(ognlContext, root);  
  
        if (resultType != null) {  
            result = getTypeConverter(context).convertValue(context, root, null, null, result, resultType);  
        }  
        return result;  
    }  

3.赋值:

/** 
*  setValue 有多个重载方法, 
*  setValue(String expression, Object root, Object value) 
*  setValue(String expression, Map context, Object root, Object value) 
*  setValue(Object tree, Object root, Object value) 
*  setValue(Object tree, Map context, Object root, Object value) 
*  最终都调用这个方法 
*  参数:tree 由对表达式解析(Ognl.parseExpression(expression))而生成的对象 
*       value 要设定的值 
*       root 被赋值对象 
*        
**/     
 public static void setValue(Object tree, Map context, Object root, Object value)  
            throws OgnlException  
    {  
        OgnlContext ognlContext = (OgnlContext) addDefaultContext(root, context);  
        Node n = (Node) tree;  
  
        if (n.getAccessor() != null) {  
            n.getAccessor().set(ognlContext, root, value);  
            return;  
        }  
  
        n.setValue(ognlContext, root, value);  
    }  

Ognl表达式语法:

 http://commons.apache.org/proper/commons-ognl/language-guide.html

Ognl使用示例:

    (如果一个表达式经常用到,最好先解析Ognl.parseExpression(expression),然后每次使用解析后的对象取值或赋值,这样更有效率)

public class OgnlTest {  
      
      
    @Test  
    public void testRootProperty(){  
        try{  
              
            String companyNameInit=" x company";  
            String companyNameNew=" y company";  
              
            Company company  = new Company();  
            company.setCompanyName(companyNameInit);  
            Object root = company;  
              
            Object tree = Ognl.parseExpression("companyName");//表达式多次使用时,先编译比较好,供以后多次调用  
              
            String companyName = (String)Ognl.getValue(tree, root);//取root的属性  
            Assert.assertEquals(companyName, companyNameInit);  
              
           
            Ognl.setValue(tree, root, companyNameNew);//为companyName设置新值  
              
            companyName = (String)Ognl.getValue(tree, root);//取root的属性  
            Assert.assertEquals(companyName, companyNameNew);  
        }catch(Exception e){  
            e.printStackTrace();  
        }  
    }  
      
    @Test  
    public void testContextProperty(){  
        try{  
            Map context = new HashMap();  
            context.put("A", "A");  
            context.put("B", "B");  
            context.put("C", "C");  
            Object root = new Object();  
              
            String a = (String)Ognl.getValue("#A", context, root);  
            Assert.assertEquals("A", a);  
              
        }catch(Exception e){  
            e.printStackTrace();  
        }  
    }  
    @Test  
    public void testTypeConverter(){  
        try{  
            Company company  = new Company();  
            company.setAsset(12000000);  
            Object root = company;  
              
            double assetD = (Double)Ognl.getValue("asset", root,Double.TYPE);//取root的属性,asset原来long型,使用类型转换为double  
            Assert.assertEquals(assetD, 12000000d);  
              
            Ognl.setValue("asset", root, 12.11f);//修改 asset 新值为float类型,会自动转换为Long型  
            long asset = (Long)Ognl.getValue("asset", root);//取root的属性asset  
            Assert.assertEquals(asset, 12);  
        }catch(Exception e){  
            e.printStackTrace();  
        }  
    }  
    @Test  
    public void testList(){  
        try{//数组,List set ognl 表达式格式相同  
            Company company  = new Company();  
            company.setEmployeeNum(10);  
            List<Employee> employeeList = new ArrayList<Employee>();  
            company.setEmployeeList(employeeList);  
            for(int i=0;i<10;i++){  
                Employee employee = new Employee();  
                employee.setAge(i);  
                employeeList.add(employee);  
            }  
            Object root = company;  
              
            int age = (Integer)Ognl.getValue("employeeList[0].id",root);//获取LIST中元素的属性  
            Assert.assertEquals(0, age);  
  
            Ognl.setValue("employeeList[0].id", root, 99);//设置List元素中的属性  
              
            age = (Integer)Ognl.getValue("employeeList[0].id",root);  
            Assert.assertEquals(age, 99);  
              
        }catch(Exception e){  
            e.printStackTrace();  
        }  
    }  
    @Test  
    public void testMap(){  
        try{  
              
            Company company  = new Company();  
            Map employeeMap = new HashMap();  
            Employee employee = new Employee();  
            employee.setAge(20);  
            employee.setId(100021);  
            employee.setName("yanlei");  
            employeeMap.put(employee.getName(), employee);  
            company.setEmployeeMap(employeeMap);  
            Object root = company;  
            Map context = new HashMap();  
              
            //#取root中的Map中的属性值,前提root得有getEmployeeMap()方法  
            int id = (Integer)Ognl.getValue("employeeMap.yanlei.id", context,root);//取root中employeeMap属性中的key=yanlei的Employee的id值  
            Assert.assertEquals(id, 100021);  
              
            Ognl.setValue("employeeMap.yanlei.id", root, 999);//修改ID的值  
              
            id = (Integer)Ognl.getValue("employeeMap.yanlei.id", context,root);//获取修改之后ID值  
            Assert.assertEquals(id, 999);  
              
              
        }catch(Exception e){  
            e.printStackTrace();  
        }  
    }  
      
      
    @Test  
    public void testCallMethod(){  
        try{  
              
              
            Company company  = new Company();  
            company.setEmployeeNum(10);  
            List<Employee> employeeList = new ArrayList<Employee>();  
            company.setEmployeeList(employeeList);  
            for(int i=0;i<10;i++){  
                Employee employee = new Employee();  
                employeeList.add(employee);  
            }  
            Object root = company;  
              
              
            int employeeNum = (Integer)Ognl.getValue("employeeNum", root);  
              
            //方法调用  
            int employeeNum1 = (Integer)Ognl.getValue("employeeList.size()", root);//调用List.size()方法  
            Assert.assertEquals(employeeNum,employeeNum1);  
              
            Ognl.getValue("employeeList.remove(0)", root);//调用list.remove方法  
            employeeNum1 = (Integer)Ognl.getValue("employeeList.size()", root);  
            Assert.assertEquals(employeeNum-1,employeeNum1);  
        }catch(Exception e){  
            e.printStackTrace();  
        }  
    }  
      
    @Test  
    public void testCollection(){//  
        try{  
            List list = new ArrayList();  
            Set set = new HashSet();  
            char m = 'A';  
            Employee [] array = new Employee [10];  
            for(int i=0;i<10;i++){  
                Employee employee = new Employee();  
                employee.setAge(20+i);  
                employee.setName(m+"");  
                list.add(employee);  
                set.add(employee);  
                array[i]= employee;  
                m++;  
            }  
            HashMap root = new HashMap();  
            root.put("list",list);  
            root.put("set",set);  
            root.put("array",array);  
              
            Map context = new HashMap();  
            Object obj = Ognl.getValue("list.{name}", context,root);//提取List中所有元素的某个公用属性值,而生成新的集合ArrayList   
            System.out.println(obj.getClass()+":"+obj);//输出:java.util.ArrayList:[A, B, C, D, E, F, G, H, I, J]  
              
            obj = Ognl.getValue("set.{name}", context,root);//提取SET中所有元素的某个公用属性值,而生成新的集合ArrayList  
            System.out.println(obj.getClass()+":"+obj);//输出:class java.util.ArrayList:[F, E, D, B, A, J, I, G, C, H]  
              
            obj = Ognl.getValue("array.{name}", context,root);//提取数组中所有元素的某个公用属性值,而生成新的集合ArrayList  
            System.out.println(obj.getClass()+":"+obj);//输出:class java.util.ArrayList:[A, B, C, D, E, F, G, H, I, J]  
              
              
            int size = (Integer)Ognl.getValue("list.{? #this.age>20}.size()", context,root);//提取List中所有元素的age>20的所有元素,而生成新的集合ArrayList,再调用ArrayList.size   
            Assert.assertEquals(9, size);  
              
            String name = (String)Ognl.getValue("list.{^ #this.age>20}[0].name", context,root);//提取List中所有元素的age>20的第一个元素生成ArrayList,再获取它中唯一元素的name属性  
            Assert.assertEquals("B", name);  
              
            name = (String)Ognl.getValue("list.{$ #this.age>20}[0].name", context,root);//提取List中所有元素的age>20的最后一个元素生成ArrayList,再获取它中唯一元素的name属性  
            Assert.assertEquals("J", name);  
              
        }catch(Exception e){  
            e.printStackTrace();  
        }  
    }  
    @Test  
    public void testMix() {  
        try{  
              
            Company company  = new Company();  
            Map employeeMap = new HashMap();  
            Employee employee = new Employee();  
            employee.setId(100021);  
            employee.setName("x");  
            employeeMap.put(employee.getName(), employee);  
            company.setEmployeeMap(employeeMap);  
            Object root = company;  
              
            Map context = new HashMap();  
            context.put("x", "X 's address is m street ");  
              
            String address = (String)Ognl.getValue("#x", context,root);//取content(Map)中的key=x的对象  
            Assert.assertEquals(address, "X 's address is m street ");  
              
            //#取root中的Map中的属性值,前提root得有getEmployeeMap()方法  
            int id = (Integer)Ognl.getValue("employeeMap.x.id", context,root);//取root中employeeMap属性中的key=A的Employee的id值  
            Assert.assertEquals(id, 100021);  
              
  
              
            //表达式中的+号,分隔子表达式,ognl分别对子表达式取值,再连接  
            //常量的表示:字符串需要用单引号引起来。  
            String message = (String)Ognl.getValue("\'employee name is x, id:\'+employeeMap.x.id+', '+#x", context,root);//  
            Assert.assertEquals(message, "employee name is x, id:100021, X 's address is m street ");  
              
          
              
        }catch(Exception e){  
            e.printStackTrace();  
        }  
    }  
    @Test  
    public void testLogic(){  
            try{  
                Company company  = new Company();  
                company.setAsset(1232);  
                company.setCompanyName("k company");  
                company.setEmployeeNum(200);  
                Object root = company;  
                Object obj = Ognl.getValue("(asset % 10 )== 2", root);  
                Assert.assertEquals(true, obj);  
                  
                obj = Ognl.getValue("(asset % 10 )== 2", root);  
                Assert.assertEquals(true, obj);  
                  
                obj = Ognl.getValue("asset > 100? 1:2", root);  
                Assert.assertEquals(1, obj);  
                  
                  
  
                obj = Ognl.getValue("asset = 1000", root);  
                Assert.assertEquals(1000, obj);  
                  
                obj = Ognl.getValue("asset == 1000? 'success':'fail'", root);  
                Assert.assertEquals("success", obj);  
                  
                obj = Ognl.getValue("asset > 1000 && employeeNum>100", root);  
                Assert.assertEquals(false, obj);  
                  
                obj = Ognl.getValue("asset >= 1000 || employeeNum>=100", root);  
                Assert.assertEquals(true, obj);  
                  
                obj = Ognl.getValue("8 & 0xE ", root);  
                Assert.assertEquals(8, obj);  
                  
                obj = Ognl.getValue("8 | 0xE ", root);  
                Assert.assertEquals(14, obj);  
                  
                obj = Ognl.getValue("8 ^ 0xE ", root);  
                Assert.assertEquals(6, obj);  
                  
                obj = Ognl.getValue("~8", root);  
                Assert.assertEquals(-9, obj);  
                  
                obj = Ognl.getValue("companyName=null", root);  
                Assert.assertEquals(null, obj);  
                  
                obj = Ognl.getValue("companyName", root);  
                Assert.assertEquals(null, obj);  
                  
                  
                obj = Ognl.getValue("companyName != null", root);  
                Assert.assertEquals(false, obj);  
                  
                obj = Ognl.getValue("companyName == null", root);  
                Assert.assertEquals(true, obj);  
                  
                obj = Ognl.getValue("!(companyName == null)", root);  
                Assert.assertEquals(false, obj);  
                  
                int m = 0xf;  
                  
            }catch(Exception e){  
                e.printStackTrace();  
            }  
    }  
}  

 类似资料: