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. 【题解】有标号的DAG计数3

    [HZOI 2015] 有标号的DAG计数 III 我们已经知道了\(f_i\)表示不一定需要联通的\(i\)节点的dag方案,考虑合并 参考[题解]P4841 城市规划(指数型母函数+多项式Ln), ...

  2. 洛谷$1541$ 乌龟棋 线性$DP$

    Luogu   CH Sol f[i]表示走到第i个格子时获得的最大分数 发现转移与各个爬行卡片的数量有关,一共只有4种卡片 所以就把这四种卡片的已使用张数也放进状态,f[i][a][b][c][d] ...

  3. MySQL保存 emoji 表情(微信昵称表情)

    问题分析 在微信开发过程中,总是会遇到带有emoji表情昵称的微信用户无法自动登录的问题. 后台代码抛出类似下面的异常信息. java.sql.SQLException: Incorrect stri ...

  4. java数据库学习路线和必学知识点!

    java数据库必学知识点! 分享一下数据库的学习路线和必学的知识点! 掌握mysql,Oracle在各个平台上的安装及使用 Mysql数据库基础 mysql概述.优点.运行原理及内存结构 mysql数 ...

  5. Sample Codes之Query features from a FeatureLayer

    除了地图基本的放大缩小等功能,在webgis上的二次开发中,查询功能 通常作为需求的一部分需要我们去实现,今天就给大家详细的分析实例代码中的查询功能:Query features from a Fea ...

  6. ip转十进制(PHP、MySQL)

    mysql与php中都提供了IP转换十进制数函数 1. IP 由点分格式,转换为数字格式,代码如下: mysql> select inet_aton('127.0.0.1'); +------- ...

  7. Java之IO流用法总结

    Java的IO流概述:1.I/O是Input/Output的缩写,I/O技术是非常实用的技术,用于处理设备之间的数据传输.如读/写文件,网络通讯等.2.Java程序中,对于数据的输入/输出操作以“流( ...

  8. 打造m3u8视频(流视频)下载解密合并器(kotlin)

    本文是对我原创工具m3u8视频下载合并器关键代码解析及软件实现的思路的讲解,想要工具的请跳转链接 1.思路说明 思路挺简单,具体步骤如下: 下载m3u8文件 解析m3u8文件获得ts文件列表 根据文件 ...

  9. ASP.Net MVC 引用动态 js 脚本

    希望可以动态生成 js  发送给客户端使用. layout页引用: <script type="text/javascript" src="@Url.Action( ...

  10. 1、使用 as 而不要用 is

    public class ShouldAsNotIs { public void ShouldAs() { object a = new ShouldAsNotIs(); var b = a as S ...