1、Struts与OGNL的结合原理

(1)值栈:

OGNL表达式要想运行就要准备一个OGNLContext对象,Struts2内部含有一个OGNLContext对象,名字叫做值栈。

值栈也由两部分组成,一部分叫做root,里面放置的是栈,另一部分是context放入的是数据中心。

(2)栈:

利用了栈先进先出的特点,每次放入元素的时候是放入到索引为零的位置,取出的时候也是取出索引为零的元素,即:从下图的最上方元素取,符合栈的先进先出的特性。

2、<s:debug>标签(查看值栈中的内容)

(1)root(栈)

默认情况下栈中存放当前访问的Action。

(2)context:

存放以下这些东西:

即:

3、Struts2与OGNL结合的体现

(1)Action以属性名的方式获取数据解析:

直接输出属性名,保持和表单的name属性的值相同。

表单将数据提交给拦截器,拦截器获取到“name=zhai”后,交给OGNL处理,OGNL从root中拿到name属性并赋值为“zhai”,由此,Action获取到了表单提交的数据。

(2)对象方式:

表单:

获取:

OGNL从栈顶获得user对象后,获得其name属性并将其值设置为“zhai”,由此,Action获取到了表单提交的数据。

(3)模型驱动

OGNL获取到name=zhai后,在值栈的root中,将user压入栈顶,并给user中的name赋值,也就是说从栈顶取元素并赋值。

原理演示:

创建一个Action:

public class ActionStack extends ActionSupport implements Preparable {
User user=new User();
public String execute(){
System.out.println(user);
return "success";
} @Override
public void prepare() throws Exception {
ValueStack valueStack=ActionContext.getContext().getValueStack();
valueStack.push(user);
}
}

实现Preparable接口的原因:

要在赋值前将user压入栈顶 ,而将获取栈的代码和将user对象压入栈顶的代码写入到prepare()函数中的目的正是获取栈并在赋值前将user对象压入栈顶。

源码分析:

 <interceptor-stack name="defaultStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="alias"/>
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="i18n"/>
<interceptor-ref name="prepare"/>
<interceptor-ref name="chain"/>
<interceptor-ref name="scopedModelDriven"/>
<interceptor-ref name="modelDriven"/>
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="datetime"/>
<interceptor-ref name="multiselect"/>
<interceptor-ref name="staticParams"/>
<interceptor-ref name="actionMappingParams"/>
<interceptor-ref name="params"/>
<interceptor-ref name="conversionError"/>
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="workflow">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="debugging"/>
<interceptor-ref name="deprecation"/>
</interceptor-stack>

在众多的拦截器中,params拦截器位置相对靠后,因此需要将params拦截器放到prepare拦截器的位置,以实现赋值前将user压入栈顶。

那么如何操作呢?打开prepare拦截器的源码可知要调用prepare拦截器需要实现Preparable接口并调用 prepare()方法。

配置Struts的配置文件、创建表单、User类后将表单数据提交给Action:

<body>
<form action="${pageContext.request.contextPath}/s/ActionStack">
用户名:<input type="text" name="username"/><br>
<input type="submit" value="提交"/>
</form>
</body>
public class ActionStack extends ActionSupport implements Preparable {
User user=new User();
public String execute(){
System.out.println(user);
return "success";
} @Override
public void prepare() throws Exception {
ValueStack valueStack=ActionContext.getContext().getValueStack();
valueStack.push(user);
}
}

4、在struts.xml配置文件中的使用

(1)创建两个Action:

Action1:

public class Action1 extends ActionSupport {
private String name; public String execute(){
name="zhang";
return "success";
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} }

Action2:

public class Action2 extends ActionSupport {
public String execute(){
return "success";
}
}

(2)配置Struts.xml配置文件,使得访问Action1的时候能够重定向到Action2,:

<struts>
<package name="action" namespace="/a" extends="struts-default">
<action name="Action2" class="pers.zhb.hello.Action2" method="execute">
<result name="success" type="dispatcher">hello.jsp</result>
</action>
<action name="Action1" class="pers.zhb.hello.Action1" method="execute">
<result name="success" type="redirectAction">
<param name="actionName">Action2</param>
<param name="namespace">/a</param>
<param name="name">${name}</param>
</result>
</action>
</package>
</struts>

(3)访问Action1:

也就是说在配置struts.xml配置文件的时候,在<param>标签内部将name属性的值设置为属性不能识别的值,就可以在重定向的时候将参数加到另外一个Action。

Struts2与OGNL的联系的更多相关文章

  1. Struts2的OGNL表达式语言

    一.OGNL的概念 OGNL是Object-Graph Navigation Language的缩写,全称为对象图导航语言,是一种功能强大的表达式语言,它通过简单一致的语法,可以任意存取对象的属性或者 ...

  2. Struts2之OGNL

    一.OGNL是什么? OGNL(Object-Graph Navigation Language)对象图导航语言,是一种表达式语言,它可以 1.遍历对象的结构图 2.存取对象的属性(实例属性和静态属性 ...

  3. Struts2对Ognl的支持

                                                      Struts2对Ognl的支持 一. 写作背景 由于工作性质的变化,最近一直在研究struts2,从 ...

  4. Struts2的OGNL标签详解

    一.Struts2可以将所有标签分成3类: UI标签:主要用于生成HTML元素的标签. 非UI标签:主要用于数据库访问,逻辑控制等标签. Ajax标签:用于Ajax支持的标签. 对于UI标签,则有可以 ...

  5. struts2之OGNL和struts2标签库和ValueStack对象

    OGNL简介: (1)OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目.  struts2框架默认就支持Ognl表达式语言(所以 ...

  6. 2018.11.25 struts2与OGNL表达式的结合(高级)

    两者的结合原理 底层源码分析 栈原理 先进后出 我们的valuestack其实是一个接口 在实现类中有这个参数 CompoundRoot的类继承的是ArrayList,具体实现弹栈和压栈的方法具体实现 ...

  7. 【Struts2】Ognl与ValueStack

    一.OGNL 1.1 概述 1.2 OGNL 五大类功能 1.3 演示 二.ValueStack 2.1 概述 2.2 ValueStack结构 2.3 结论 2.3 一些问题 三.OGNL表达式常见 ...

  8. JavaWeb_(Struts2框架)Ognl小案例查询帖子

    此系列博文基于同一个项目已上传至github 传送门 JavaWeb_(Struts2框架)Struts创建Action的三种方式 传送门 JavaWeb_(Struts2框架)struts.xml核 ...

  9. Struts2之OGNL与ValueStack

    时间:2017-1-12 12:02 --OGNL1.OGNL表达式是什么    OGNL的全称是Object-Graph Navigation Language的缩写,中文名是对象图导航语言,它是一 ...

随机推荐

  1. $CF908D\ New\ Year\ and\ Arbitrary\ Arrangement$ 期望$dp$

    正解:期望$dp$ 解题报告: 传送门$QwQ$ 阿关于题目里那个形如$ab$的子序列我说下,,,我我我之前$get$了好久$QAQ$.这里子序列的个数的定义是这样儿的,举个$eg$,$aabb$,就 ...

  2. 初次在cmd使用git命令上传项目至github方法(笔记)

    在一切开始之前,先推荐一个git简易工具书--Git_Cheat_Sheet,非常适合新手.自行搜索即可,也有热心者提供了中文版. 一.下载 Git 从Git官网下载Git安装包 https://gi ...

  3. 【一起学源码-微服务】Ribbon 源码一:Ribbon概念理解及Demo调试

    前言 前情回顾 前面文章已经梳理清楚了Eureka相关的概念及源码,接下来开始研究下Ribbon的实现原理. 我们都知道Ribbon在spring cloud中担当负载均衡的角色, 当两个Eureka ...

  4. js滑动导航栏点击后居中效果

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. 你确定你了解什么是linux系统?

    1.什么是linux发行版 就Linux的本质来说,它只是操作系统的核心,负责控制硬件.管理文件系统.程序进程等,并不给用户提供各种工具和应用软件.所谓工欲善其事,被必先利其器,一套在优秀的操作系统核 ...

  6. 一个简单的spring boot程序

    搭建一个spring boot项目十分的方便,网上也有许多,可以参考 https://www.cnblogs.com/ityouknow/p/5662753.html 进行项目的搭建.在此我就不详细介 ...

  7. AQS 原理以及 AQS 同步组件总结

    1 AQS 简单介绍 AQS 的全称为(AbstractQueuedSynchronizer),这个类在 java.util.concurrent.locks 包下面. AQS 是一个用来构建锁和同步 ...

  8. 来吧,一文彻底搞懂Java中最特殊的存在——null

    没事的时候,我并不喜欢逛 P 站,而喜欢逛 programcreek 这些技术型网站,于是那天晚上,在夜深人静的时候,我就发现了一个专注基础但不容忽视的主题.比如说:Java 中的 null 到底是什 ...

  9. 深入理解vue的watch

    深入理解vue的watch vue中的wactch可以监听到data的变化,执行定义的回调,在某些场景是很有用的,本文将深入源码揭开watch额面纱 前言 watch的使用 watch的多种使用方式 ...

  10. PBFT && RBFT算法流程

    PBFT && RBFT算法流程以及其实现(上) 这篇文章主要是讲一下RBFT中共识算法流程以及节点的加入的流程.在下一篇博客中,将使用Java实现该算法. 传统的PBFT算法无法动态 ...