Ognl表达式引擎

Ognl框架
1说明:Struts2只是把Ognl作为它的表达式引擎,此文章SAMPLE只是单独的Ognl框架,与struts2没有任何联系
2.能力有限,代码中注释难免有误请包含或指证
3.目的:分享, 可作为”数据流转”入口
4.内容:以下为主代码内容,javaBean(User和Company)就不贴出来了,看代码里的setter就可以构造出javaBean了

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import ognl.Ognl;
import ognl.OgnlContext;
import ognl.OgnlException;

/**
* 引入jar包:ognl.jar +javassist.jar
*
* OGNL表达式引擎
* 1.表达式引擎作用:
* 略
* 2.数据流转
* 表达式引擎应用场景:略
*
* 3.设计模式:类似策略模式/监听器模式
* 根据root类型,指定具体的PropertyAccessor
* 比如,root为List则指派ListPropertyAccessor处理相应逻辑
* root为Array则指派ArrayPropertyAccessor处理相应逻辑
*
* 4.调用层次:Ognl
Node
SimpleNode
ASTProperty
SimpleNode
OgnlRuntime
PropertyAccessor{ Object getProperty(Map context, Object target, Object name)}

  • 5.JJTree 一个有意思的东西,有兴趣的可以看看
    *
    *
  • @author 拈花为何不一笑
  • @since 8/23/2018
  • */
    public class OgnlExpressEngine {

    /**

    • 单元测试
      */
      public static void main(String[] args) {

// testOgnlForObj();
// testOgnlForMap();
// testOgnlForList();
testOgnlForArray();

    System.exit(0);
}


/**
 * Ognl访问数组
 *  访问数组元素rootInt[2],如何使用Ognl中的方法getValue呢
 *      猜想了下expression处,用[2]代替,
 *          Ognl.getValue(expression, context,root);果真对了。
 *  其它类似,比如map,list,set,obj平常你怎么访问它们的就试着写expression
 * 
 *  源码片段:
 *       if (index instanceof Number)
            {
                int i = ((Number) index).intValue();

                result = (i >= 0) ? Array.get(target, i) : null;
            } else
            {
                throw new NoSuchPropertyException(target, index);
            }
 */
private static void testOgnlForArray() {
    int[] rootInt = new int[]{1,3,56,8,10};

    OgnlContext context = new OgnlContext() ;
    context.put("rootInt", rootInt);
    context.setRoot(rootInt);

    Object result = null;
    try {

        result = Ognl.getValue("[2]", context,rootInt);
        System.out.println("Ognl访问数组中的元素:" + result);

        //使用DynamicSubscript访问Array
        // [^] 表示list中的第一个元素, [$] 表示list中的最后一个元素, [|] 表示list中的中间元素, and [*]表示所有元素
        Object firstElemet = Ognl.getValue("[^]", context,rootInt);
        Object lastElement = Ognl.getValue("[$]", context,rootInt);
        Object midElement = Ognl.getValue("[|]", context,rootInt);
        Object allElement = Ognl.getValue("[*]", context,rootInt);

        System.out.println("firstElemet:" + firstElemet + "\n"
                        + "lastElement:" + lastElement + "\n"
                        + "midElement:" + midElement + "\n"
                        + "allElement:" + allElement + "\n"
        );
        System.out.println("Array工具操作数据对象allElement:" + Array.getInt(allElement, 2));

        //数组中的嵌套,带大家弄个好玩的初始化对象数组
        User[] users = { new User(){
                        {setId(6661);setName("洪宇");}
                    },
                    new User(){
                        {setId(6662);setName("洪宙");}
                    }};
        OgnlContext context2 = new OgnlContext();
        context2.put("users", users);
        context2.setRoot(users);
        Object firtElement_id = Ognl.getValue("[0].id", context2, context2.getRoot());
        Object firtElement_name = Ognl.getValue("[0].name", context2, context2.getRoot());
        Object secondElement_id = Ognl.getValue("[1].id", context2, context2.getRoot());
        Object secondElement_name = Ognl.getValue("[1].name", context2, context2.getRoot());
        System.out.println("Ognl访问数组中的嵌套元素:\n" 
                    + "firtElement_id: " + firtElement_id  +", firtElement_name: "+ firtElement_name + "\n"
                    + "secondElement_id: " + secondElement_id  +", secondElement_name: " + secondElement_name + "\n"
            );

    }catch (OgnlException e) {
        e.printStackTrace();
    }

}

/**
 * Ognl访问List集合
 *  
 * 遇到异常(很眼熟吧):
 *  ognl.ParseException: Encountered "<EOF>" at line 1, column 3.
        Was expecting one of:
        ":" ...
        "not" ...
        "+" ...
        "-" ...
        "~" ...
        "!" ...
        "(" ...
        "true" ...
        "false" ...
        "null" ...
        "#this" ...
        "#root" ...
        "#" ...
        "[" ...
        "{" ...
        "@" ...
        "new" ...
        <IDENT> ...
        <DYNAMIC_SUBSCRIPT> ...
        "\'" ...
        "`" ...
        "\"" ...
        <INT_LITERAL> ...
        <FLT_LITERAL> ...

      原因:断点时用到inspect查看表达式的值时抛出异常,位于Ognl的parseExpression方法
        中的表达式:return parser.topLevelExpression();
      解决方案:在此调试中的表达式处,不使用MyEclipse inspect就OK了

    源码片段:
         if (name instanceof String) {
        Object result = null;

        if (name.equals("size")) {
            result = new Integer(list.size());
        } else {
            if (name.equals("iterator")) {
                result = list.iterator();
            } else {
                if (name.equals("isEmpty") || name.equals("empty")) {
                    result = list.isEmpty() ? Boolean.TRUE : Boolean.FALSE;
                } else {
                    result = super.getProperty(context, target, name);
                }
            }
        }

        return result;
    }

        if (name instanceof Number)
        return list.get(((Number) name).intValue());

 */
private static void testOgnlForList() {

    //list中简单元素
    List<String> rootList = new ArrayList<String>();
    rootList.add("hello");
    rootList.add("tomson");
    rootList.add("and you");

    OgnlContext context = new OgnlContext() ;
    context.put("rootList", rootList);
    context.setRoot(rootList);

    Object result = null;
    try {

        result = Ognl.getValue("[0]", context,rootList);
        System.out.println("Ognl访问list中的元素: " + result);

        //使用DynamicSubscript访问List
        // [^] 表示list中的第一个元素, [$] 表示list中的最后一个元素, [|] 表示list中的中间元素, and [*]表示所有元素
        Object firstElemet = Ognl.getValue("[^]", context,rootList);
        Object lastElement = Ognl.getValue("[$]", context,rootList);
        Object midElement = Ognl.getValue("[|]", context,rootList);
        Object allElement = Ognl.getValue("[*]", context,rootList);
        System.out.println("firstElemet:" + firstElemet + "\n"
                        + "lastElement:" + lastElement + "\n"
                        + "midElement:" + midElement + "\n"
                        + "allElement:" + allElement + "\n"
        );


    } catch (OgnlException e) {
        e.printStackTrace();
    }

    //2.list嵌套元素
    User user1 = new User();
    user1.setId(9527);
    user1.setName("周星星");

    User user2 = new User();
    user2.setId(9528);
    user2.setName("刘德华");

    List<User> list = new ArrayList<User>();
    list.add(user1);
    list.add(user2);

    OgnlContext context2 = new OgnlContext();
    context2.put("list", list);
    context2.setRoot(list);

    Object result1;
    Object firstResult_id;
    Object firstResult_name;
    Object secondResult_id;
    Object secondResult_name;
    try {
         result1 = Ognl.getValue("size", context2, context2.getRoot());

         firstResult_id = Ognl.getValue("[0].id", context2, context2.getRoot()); 
         firstResult_name = Ognl.getValue("[0].name", context2, context2.getRoot());

         secondResult_id = Ognl.getValue("[1].id", context2, context2.getRoot()); 
         secondResult_name = Ognl.getValue("[1].name", context2, context2.getRoot());

         System.out.println("Ognl访问list中的嵌套元素: " + "[\n" 
                 + "size: " + result1 + "\n"
                 + "[0].id: " + firstResult_id +",[0].name: " + firstResult_name  + "\n"
                 + "[1].id: " + secondResult_id +",[1].name: " + secondResult_name  + "\n"
         + "]");
    } catch (OgnlException e) {
        e.printStackTrace();
    } 

}

/**
 * Ognl访问java对象
 *  源码片段:result = method.invoke(target, argsArray);
 *  通过uesr(限定全名即org.yl.domain.User)找出所有方法名包括继承到的
 *      user.getClass().getSuperclass()
 *  然后遍历所有方法名,直到getName.endsWith(Name)为真找到method
 * 再然后找这个方法下的参数argsArray
 * 最后,result = method.invoke(target, argsArray);
 */
private static void testOgnlForObj() {
    User user = new User();  
    user.setName("刘可耕");

    try {
        Object nameResult = Ognl.getValue("name", user);

        System.out.println("Ognl访问对象属性user.name:" + nameResult);

        Company com = new Company();
        com.setCompanyName("志正股份责任公司");
        user.setComh(com);//setXXX中的XXX作为expression

        Object companlyNameResult = Ognl.getValue("comh.companyName", user);
        System.out.println("Ognl访问对象嵌套的属性user.company.companyName:" + companlyNameResult);

    } catch (OgnlException e) {  
        e.printStackTrace();
    }

}

/**
 * ognl访问Map
 *  源码片段:
 *      
        if (name.equals("size")) {
            result = new Integer(map.size());
        } else {
            if (name.equals("keys") || name.equals("keySet")) {
                result = map.keySet();
            } else {
                if (name.equals("values")) {
                    result = map.values();
                } else {
                    if (name.equals("isEmpty")) {
                        result = map.isEmpty() ? Boolean.TRUE : Boolean.FALSE;
                    } else {
                        result = map.get(name);
                    }
                }
            }
        }

 */
private static void testOgnlForMap() {
     Map<String,Object> rootMap=new HashMap<String,Object>(); 
        rootMap.put("money","10000");  
        rootMap.put("3月", "业绩");
        Object values;
        Object v;
        try {
            v = Ognl.getValue("money", rootMap);
            System.out.println("******Ognl访问Map中的元素: " + v);


            values = Ognl.getValue("values", rootMap);
            Collection c = (Collection)values;
            Iterator it = c.iterator();
            while(it.hasNext()){

                String vResult = (String)it.next();
                System.out.println("vResult:" + vResult);
            }
            System.out.println("******Ognl访问Map中的values: " + values);

            User user = new User();
            user.setName("郭德纲");
            rootMap.put("user", user);
            values = Ognl.getValue("user.name", rootMap);
            System.out.println("******Ognl访问Map中嵌套的元素: " + values);

        } catch (OgnlException e) {
            e.printStackTrace();
        } 


}

}

猜你喜欢

转载自blog.csdn.net/Netaa001/article/details/81944257
今日推荐