Ognl表达式笔记

表达式作用

根据定义的语法规则,操作对象信息

表达式框架

  • Ognl(Object-Graph Navigation Language): 可以方便地操作对象属性的开源表达式语言
  • JSTL(JSP Standard Tag Library): JSP2.0集成的标准表达式语言

Ognl提供的能力

1、支持对象方法调用

2、支持类静态的方法 或 值调用
    格式: "@[类全名(包括包路径)]@[方法名|值名]"。
    例子: 
        调用类静态方法 @java.lang.String@format('user%s','getUserId')
        访问类的静态值 @com.my.module@APP_ID

3、支持赋值操作和表达式串联
    如 user.id=1,  表达式 #user.id+1, 返回2
    支持 +, -, *, /, ++, --, ==, !=, = , mod, in, not in 等操作符

4、访问OGNL上下文 (OGNL context) 和 ActionContext

5、操作集合对象

Ognl用途

  • Mybatis
  • 动态业务处理(动态逻辑、动态数据获取等)

OGNL中的#、%和$符号对比

#符号的用法
1.访问对象属性(不加#默认访问根对象)
    例如 #user.name

2.用于过滤和投影(projecting)集合
    #users.{?#this.id>=2}

    ? --获取集合中所有满足选择逻辑的对象
    ^ --获取集合中第一个满足选择逻辑的对象
    $ --获取集合中最后一个满足选择逻辑的对象

3.用来构造Map
    例如 #{'id':'1', 'name':'小明'}
%符号的用法
作用: 用于标识当前表达式是否被ognl解析器解析(前端)
    %{#user.name} 标识括号中是一个ognl表达式,需要解析
$符号的用法
作用: 引用值
用途:
    1.在国际化资源文件中,引用OGNL表达式
    2.在Struts 2框架的配置文件中引用OGNL表达式
        ${title}

简单Demo

  • 导入Maven包
<!-- ognl表达式 -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.0</version>
    <scope>compile</scope>
</dependency>
  • OgnlUtil
package com.utils;

import org.apache.ibatis.ognl.Ognl;
import org.apache.ibatis.ognl.OgnlContext;
import org.apache.ibatis.ognl.OgnlException;

public class OgnlUtil {

    /**
     * 根据OGNL表达式进行取值操作
     *
     * @param expression ognl表达式
     * @param ctx  ognl上下文
     * @param rootObject ognl根对象
     * @return
     */
    public static Object getValue(String expression,
                                  OgnlContext ctx,
                                  Object rootObject) {
        try {
            return Ognl.getValue(expression, ctx, rootObject);
        } catch (OgnlException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 根据OGNL表达式进行赋值操作
     *
     * @param expression ognl表达式
     * @param ctx ognl上下文
     * @param rootObject ognl根对象
     * @param value 值对象
     */
    public static void setValue(String expression, OgnlContext ctx,
                                Object rootObject, Object value) {
        try {
            Ognl.setValue(expression, ctx, rootObject, value);
        } catch (OgnlException e) {
            throw new RuntimeException(e);
        }
    }
}
  • module对象
public class Employee {

    private int id;
    private String title;

    public Employee(){}

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}

public class User {

    private int id;
    private String name;

    public User(){}
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

  • test

public class OgnlTest {

    public static void main(String[] args) {
        Employee emp = new Employee();
        OgnlContext ctx = initOgnlContext(emp);

        //测试获取元素
        testGet(ctx,emp);

        //测试设置元素
        testPut(ctx,emp);
        
        /**
         * 执行结果
         研发部
         小明
         研发部
         2
         [{"id":2,"name":"小王"},{"id":3,"name":"小六"}]
         {"id":3,"name":"小六"}
         {"id":1,"title":"测试新标题"}
         [{"id":1,"name":"小明"},{"id":2,"name":"小王"},{"id":4,"name":"小黄"}]      
         **/
    }

    //测试设置元素
    private static void testPut(OgnlContext ctx,Employee emp){
        OgnlUtil.setValue("title",ctx,emp,"测试新标题");
        Employee newEmp = (Employee) OgnlUtil.getValue("#emp", ctx, emp);
        System.out.println(JSON.toJSONString(newEmp));

        //设置集合
        User user = new User();
        user.setId(4);
        user.setName("小黄");
        OgnlUtil.setValue("#users[2]",ctx,emp,user);

        List<User> users = (List<User>) OgnlUtil.getValue("#users",ctx,emp);
        System.out.println(JSONArray.toJSONString(users));
    }

    //测试获取元素
    private static void testGet(OgnlContext ctx,Employee emp){
        //取出ognl上下文(容器)中的根元素的id属性,取根节点的对象,可以无需指定命名空间
        String id = (String) OgnlUtil.getValue("title", ctx, emp);
        System.out.println(id);

        // 表达式#user.name将执行user.getName()
        //取出ognl上下文中非根对象的name值,非根对象取值必须通过指定的类实例去取
        String uName = (String) OgnlUtil.getValue("#user.name",ctx, emp);
        System.out.println(uName);

        // 当然根对象也可以使用#emp.title表达式进行访问
        String empName = (String) OgnlUtil.getValue("#emp.title", ctx, emp);
        System.out.println(empName);

        Integer id2 = (Integer) OgnlUtil.getValue("#user.id+1", ctx, emp);
        System.out.println(id2);

        List<User> users = (List<User>) OgnlUtil.getValue("#users.{?#this.id>=2}",ctx,emp);
        System.out.println(JSONArray.toJSONString(users));

        User user = (User) OgnlUtil.getValue("#users[2]",ctx,emp);
        System.out.println(JSON.toJSONString(user));
    }

    //初始化Ognl上下文
    public static OgnlContext initOgnlContext(Employee root){
        root.setId(1);
        root.setTitle("研发部");

        User user = new User();
        user.setId(1);
        user.setName("小明");

        User user2 = new User();
        user2.setId(2);
        user2.setName("小王");
        User user3 = new User();
        user3.setId(3);
        user3.setName("小六");

        List<User> users = new ArrayList<>();
        users.add(user);
        users.add(user2);
        users.add(user3);

        // 创建OGNL下文,而OGNL上下文实际上就是一个Map对象
        OgnlContext ctx = new OgnlContext();
        ctx.put("emp",root);
        ctx.put("user",user);
        ctx.put("users",users);
        ctx.put("maxAge",24);
        ctx.put("minAge",18);

        //设置上下文根对象,一个上下文中只有一个根对象
        ctx.setRoot(root);

        return ctx;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值