• OGNL表达式及ognl与struts2的结合


    一.ognl表达式

      1.ognl表达式跟el表达式都是对象视图导航语言,不过ognl比el在功能上更加强大,除了输出外,还可以为对象赋值,调用对象方法,调用静态方法等

      2.在EL中我们取值是从11个内置对象中获取,而我们的ognl是从ognlContext中来获取。

      3.ognlContext实质是一个map,这个map还分为两部分,root部分和context部分,root部分中可以任意类型的对象作为root对象,且root对象只能有一个;context部分说白也是map,你调用ognlContext对象的put存储键值对,其实是属于放在了context中,主要是为了区分root和context

    在下述操作前,先做一些对象准备工作,如图:

    二.如何从ognlContext对象中取值?

      1.可以调用Ognl.getValue(expression, ognlContext, root),参数一是表达式,参数二是ognlContext对象,参数三是ognlContext对象中的root对象

      2.如果想要获取root对象的属性,直接在表达式中写root对象的属性名,如:Ognl.getValue("name", ognlContext, root);

      3.如果想要获取context中的值,得再表达式的前面加一个#,如:Ognl.getValue("#key.name", ognlContext, root);key为键值对的键,#key就得到了值;

    三.ognl如何设置属性值?

      1.给root对象设置属性值,表达式格式是"属性名=修改后的值",如:Ognl.getValue("name='王五'", ognlContext, root);

      2.给context中键值对的值对象设置属性,如:Ognl.getValue("#key.name='多佛朗', ognlContext, root);

    四.ognl如何调用方法?

      1.调用root对象的方法,很简单,表达式直接写方法名即可,如:Ognl.getValue("getName()", ognlContext, root);如果调用的方法有返回值,则会有返回值返回

      2.context中调用值对象的方法,如:Ognl.getValue("#key.setName('大帅哥')", ognlContext, root);

    五.ognl如何调用静态方法?

      1.调用静态方法,得在类名和调用的方法名前加@,结构为:@完整类名@方法名,如:Ognl.getValue("@java.lang.Math@PI", ognlContext, u1);

    六.ognl创建List和map

      1.创建list的话,表达式中加{ },代表要创建list,如:

        Ognl.getValue("{'tom','jerry','jeck'}", ognlContext, root);创建的list是不会放到ognlContext去的,map也如此

        Ognl.getValue("{'tom','jerry','jeck'}[1]", ognlContext, root);获取指定索引的值

        gnl.getValue("{'tom','jerry','jeck'}.get(2)", ognlContext, root);获取指定索引的值

      2.创建map,表达式中加#{ },代表要创建map,如:

        Ognl.getValue("#{'tom':'18','jerry':'12','jeck':'10'}", ognlContext, root);

        Ognl.getValue("#{'tom':'18','jerry':'12','jeck':'10'}['jerry']", ognlContext, root);获取指定键的值

        Ognl.getValue("#{'tom':'18','jerry':'12','jeck':'10'}.get('tom')", ognlContext, root);获取指定键的值

    七.ognl与struts2的结合

      1.ognl其实跟struts2在技术没什么联系,不过struts2把ognl纳入进来使用而已

      2.OgnlContext对象在struts2中不叫OgnlContext了,叫值栈ValueStack;不过里面的分类还是跟之前一样,分root部分和context部分

      3.struts2已经在ValueStack已经为我们预置了要使用的东西,在root部分放置了一个List栈,在context部分放置了一个ActionContetx对象,ValueStack是一个接口,而我们去查看它的实现类OgnlValueStack源码,有两个变量,如图:

       root就是我们的list栈,而context就是我们的ActionContext

      4.比如说在List栈中,有几个user对象,user类有name属性,我们要从栈中获取name属性值时,是从栈顶的对象开始找的,如果找不到继续往下找

      5.ActionContext中引用了很多servlet原生api的东西,在我们的List栈中,默认情况下,放置的是当前访问的Action对象

    八.ognl与struts2的结合之参数接收

      1.记得在Action类中接收参数的三种方式吗?分别是属性驱动,对象驱动,模型驱动;

      2.这三种驱动的实现就是依赖我们的ognl来做的;

        (1)属性驱动;比如:表单页面提交name="username"该键值对参数到我们的Action之前,会经历20个拦截器,其中有一个params拦截器会调用ognl,ognl会解释该键值对为符合ognl表达式的语法,从我们的valueStack中,root部分的list栈中赋值,假设我们的Action对象就放置在栈顶,它会从栈顶的Action对象中查看有没有username属性,如果有给其赋值。

        (2)对象驱动;比如:表单页面提交name="user.username"该键值对参数到我们的Action之前,会经历20个拦截器,其中有一个params拦截器会调用ognl,ognl会解释该键值对为符合ognl表达式的语法,从我们的valueStack中,root部分的list栈中赋值,又假设我们的Action对象就放置在栈顶,它会从栈顶的Action对象中查看有没有user对象的属性,如果有给user对象的username赋值。

        (3)模型驱动;这个相对前面两个就有意思了,要是按照上面两个的逻辑的话,表单页面提交name="username",而我们的Action中是user成员变量(不是属性),好像解释成ognl表达式后直接放的话是不放进去的吧;

    先不谈模型驱动的接口,那如何才能让name="username"放到user对象中?我们是不是可以把Action对象中的user对象在list栈中压栈到栈顶吧,这样的话就可以根据ognl表达式赋进去了吧;

    那问题也来了,什么时候把user压栈?因为params拦截器调用ognl到valueStack进行的赋值,如果我们在它之后进行压栈的话就已经晚了,所以我们得在此之前进行压栈的操作,可以考虑在params前面的拦截器进行操作,手动实现一个Preparable接口,重写它的prepare方法,在该方法里面进行压栈即可;

    为什么可以这样做呢,是因为在params拦截器前有一个prepare拦截器,该拦截器会判断你的action是否实现了Preparable接口,若是的话会调用重写的prepare方法。

    但是呢struts2觉得这样对开发者麻烦,直接让实现ModelDriven接口,重写getModel()把你要压栈的对象传给它即可,后续的操作人家modelDriven拦截器会帮你完成,原理跟上面的是一样的。

     PS:想要获取ValueStack,可以通过ActionContext来获取,他们两个是互相引用的

    九.ognl与struts2的结合之配置文件

      1.如果Action方法的返回值是需要重定向Action且需要带参数,配置代码可以这样写:

    因为ognl会从值栈来取,开头没有#,会取list栈的栈顶对象取值,我们可以把要传的参数设置成Aciton对象的成员属性即可

  • 相关阅读:
    fabric.js 学习
    前端基础回顾
    ubuntu16 mysql 远程连接
    Django rest_framework API 随笔
    django 学习笔记
    vue 返回上一页在原来的位置
    Django mysql 改用pymysql 驱动
    Material-UI
    设置placeholder的样式
    Cookie、session和localStorage、以及sessionStorage之间的区别
  • 原文地址:https://www.cnblogs.com/ibcdwx/p/12734961.html
Copyright © 2020-2023  润新知