struts2值栈,OGNL表达式,interceptor

struts2获取servlet api

第一种获取方式
  获得原生request
  HttpServletRequest request = ServletActionContext.getRequest();
  获得原生response
  HttpServletResponse response = ServletActionContext.getResponse();
第二种获取方式
  实现ServletRequestAware,获取原生request
  实现ServletResponseAware,获取原生response

OGNL表达式

  OGNL是对象图导航语言的缩写,它是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,实现字段类型转化等功能......

  OGNL的作用:支持对象的操作,调用对象的方法,支持静态成员访问,支持静态成员访问,支持赋值操作与表达式串联

OGNL三要素:表达式 OgnlContext(上下文) Root (根)

OGNL对象操作:

@Testpublic void test1() throws Exception {//获取ognl对象OgnlContext context = new OgnlContext();//获取根Object root = context.getRoot();Object value = Ognl.getValue("'hello'.length()", context, root);System.out.println(value);}

OGNL静态成员访问

@Testpublic void test2() throws Exception {//获取ognl对象OgnlContext context = new OgnlContext();//获取根Object root = context.getRoot();Object value = Ognl.getValue("@java.lang.Math@random()", context, root);System.out.println(value);}

如果不能成功执行,是因为struts默认静态成员掉用是关闭的,需要在配置中打开;

<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>

访问OGNL上下文

@Testpublic void test3() throws Exception {//获取ognl对象OgnlContext context = new OgnlContext();//向上下文中存储数据context.put("username", "jack");//获取根Object root = context.getRoot();Object value = Ognl.getValue("#username", context, root);System.out.println(value);}

ognl操作集合

@Testpublic void test4() throws Exception {//获取ognl对象OgnlContext context = new OgnlContext();//获取根Object root = context.getRoot();Object value = Ognl.getValue("{'111','222','333'}", context, root);//这里就相当于建立了一个list集合
        System.out.println(value);//把list集合放入root根中
        context.setRoot(value);//获取list中的数据Object value2 = Ognl.getValue("[1]", context, context.getRoot());System.out.println(value2);}

这里需要特别注意的是:这里的root不能用上面的root,用上面的root会取不到list中的值

  在struts2框架中我们使用ognl表达式的作用是从valueStack中获取数据,我们在struts2框架中可以使用
ognl+valueStack达到在页面上来获取数据,这就需要使用<s:property value="表达式">来使用

要使用<s:property value="表达式">就要导入核心标签库

<%@taglib prefix="s" uri="/struts-tags" %>

下面就可以使用:

<s:property value="'hello'.length()"/>
<s:property value="@java.lang.Math@random"/>

下面介绍非常重要的值栈

  我们使用valueStack的主要目的是将action中的数据带到jsp页面,它就是一个容器;
  在struts2中它就是一个接口:com.opensymphony.xwork2.util.ValueStack
  它的实现类是:com.opensymphony.xwork2.ognl.OgnlValueStack

struts2中的action是一个多例的,每一次请求都会有一个新的action对应,所以它不存在线程安全问题;
一个valueStack对应一个action,valueStack贯穿整个action;
request--action--actionContext--valueStack
所以valueStack保存在request中

valueStack由两部分组成:

  CompoundRoot:它就是一个arraylist,主要用于存储action的相关数据
  Map<String,Object> context:就是一个map,主要用于存储一些引用,关于web开发中的相关信息
  pameters :请求参数
  request:请求对象中所有属性
  session:会话对象中所有属性
  application:application对象中的所有发展

struts2框架中使用ognl表达式来获取valueStack中的数据,使用#就是从非root根中获取数据

  获取valueStack的两种方式

  1.直接通过request获取

@Testpublic void test1() {//通过request获取ValueStack vs = (ValueStack) ServletActionContext.getRequest().getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);}

  2.使用actionContext来获取

@Testpublic void test2() {//通过actioncontext来获取ActionContext context = ActionContext.getContext();ValueStack valueStack = context.getValueStack();}

那么actionContext到底是什么呢:

  

  它是action的上下文对象,struts2使用它来保存action在执行过程中所需要的一些对象,例如:session,application
  它通过getContext()静态方法得到
  struts2会根据每一次的request请求创建actionContext,它是与线程绑定的,每一次请求就是每一个线程,每一个request
  都会创建一个action,每个action对应一个actionContext,所以每一次请求也对应着一个valueStack

  特别注意的是:valueStack存储数据的时候,主要是向root中存储;

  对于继承了ActionSupport类的action类,浏览器传入的数据是存储在model对象中;

  使用了表达式也可以从value中获取数据是因为struts2对request中的getAttribute进行了增强,,如果request域中找不到数据,就会
在valueStack中获取

 

ognl中的特殊字符

  #号:代表的是从飞root中获取数据
  %:用户强制是否要解析ognl表达式
  $:主要是从配置文件中来获取valueStack中数据

一个展示商品信息的例子

  在jsp页面中点击显示商品的连接,然后封装商品,保存然后跳转到showProduct页面

<a href="${pageContext.request.contextPath }/Demo3Action">显示商品</a>

跳转到action中处理数据:

public class Demo3Action extends ActionSupport{//封装product的数据public String show() throws Exception {List<Product> list = new ArrayList<>();//模拟数据Product p1 = new Product();p1.setName("电视");p1.setCount(100);p1.setPrice(2000);Product p2 = new Product();p2.setName("冰箱");p2.setCount(200);p2.setPrice(1000);//存储到集合
        list.add(p1);list.add(p2);//保存到值栈中ValueStack vs = ActionContext.getContext().getValueStack();System.out.println(list);vs.set("list", list);return "show";}}

跳转到显示页面

     <s:iterator value="list"><tr><td><s:property value="name"/></td><td><s:property value="count"/></td><td><s:property value="price"/></td></tr></s:iterator>

拦截器

  struts2的拦截器主要是拦截action的操作,在action的执行前或后进行一些其它功能的操作

执行过程

  当我们发送请求访问Action时,会被StrutsPrepareAndExecuteFilter拦截

在其doFilter方法内执行了

  

execute.executeAction(request, response, mapping);

这个代码执行后

  

dispatcher.serviceAction(request, response, mapping);

serviceAction方法执行

  在这个方法执行过程中会创建Action代理对象

ActionProxy proxy = getContainer().getInstance(ActionProxyFactory.class).createActionProxy(namespace, name, method, extraContext, true, false);

  通过proxy去执行了proxy.execute();
  在execute方法内return invocation.invoke();
  invocation它是ActionInvocation一个对象
  在invoke方法内,会去加载我们的配置文件,将配置文件中所有的interceptor得到进行遍历。
  在struts-default.xml文件中定义了默认加载的拦截器栈 defaultStack
  在每一个拦截器的interceptor方法内,又调用了DefaultActionInvocation的invoke方法,其实就是递归调用。

自定义interceptor

  所有的Interceptor都要实现一个接口
  在配置文件中声明Interceptor

<interceptors><interceptor name="" class=""></interceptor>
</interceptors>

  我们也可以将多个interceptor封装成一个stack

<interceptors><interceptor name="interceptor1" class=""></interceptor><interceptor name="interceptor2" class=""></interceptor><interceptor-stack name="myStack"><interceptor-ref name="interceptor1"></interceptor-ref><interceptor-ref name="interceptor2"></interceptor-ref></interceptor-stack>
</interceptors>

注意:当我们显示的引入了一个自定义的Interceptor,那么默认的defaultStack就不会在导入,需要手动导入。

 

转载于:https://www.cnblogs.com/learnjfm/p/7090759.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/429144.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何给ppt编辑页码_拒绝千篇一律:Word插入“侧边”页码,让文档别具一格!...

微信扫码观看全套Excel、Word、PPT视频之前&#xff0c;有为大家介绍过插入页码的技法&#xff0c;你还记吗&#xff1f;(点击此处&#xff0c;阅读文章)我们已知道Word插入页码的方法&#xff0c;而且我们也很会用了。但是&#xff0c;如果要插入下图所示的侧边页码&#xff0…

二、MySQL高级

mysql高级 今日目标 掌握约束的使用 掌握表关系及建表原则 重点掌握多表查询操作 掌握事务操作 1&#xff0c;约束 上面表中可以看到表中数据存在一些问题&#xff1a; id 列一般是用标示数据的唯一性的&#xff0c;而上述表中的id为1的有三条数据&#xff0c;并且 马花疼…

设计模式之 里氏替换原则

里氏替换原则(Liskov Substitution Principle, LSP)&#xff1a;所有引用父类的地方必须能使用其子类的对象。 简单来说就是 子类拥有父类所拥有的一切&#xff0c;并可以在此基础上进而扩展其他的属性和方法。转载于:https://www.cnblogs.com/blazeZzz/p/9260874.html

sql数据库去重语法_Mysql数据库中查询重复数据和去重数据 , 删除重复数据的sql及分析...

Mysql数据库中查询重复数据和去重数据 , 删除重复数据的sql及分析发布时间&#xff1a;2018-06-17 13:22,浏览次数&#xff1a;858, 标签&#xff1a;Mysqlsql数据库中有重复数据时,用到哪些sql语句?这里有若干数据,并掺杂了重复数据1. 查看过滤重复后的数据思路, group by 分…

Maven基础(总结)——入门学习

Maven基础 一、Maven概述 1.Maven是专门用于管理和构建Java项目的工具&#xff0c;它的主要功能有&#xff1a; 提供了一套标准化的项目结构提供了一套标准化的构建流程&#xff08;编译&#xff0c;测试&#xff0c;打包&#xff0c;发布……&#xff09;提供了一套依赖管理…

c#重写了窗体的OnKeyDown事件,但是不执行

设置下窗体的KeyPreview属性值为True即可 总结&#xff1a;遇到类似这样的问题&#xff0c;比如其他窗体运行没问题&#xff0c;就新建的窗体有问题。应该检查下窗体的属性。 转载于:https://www.cnblogs.com/codeDevotee/p/7093333.html

python答疑的作用_不学Python之集中答疑(5)

Python不用学&#xff0c;用用你就会。本辑答疑针对Python自然学习法二阶第二单元课程&#xff1a;Q&#xff1a;什么是字典&#xff1f;A&#xff1a;字典也是Python里面的一种多元素数据的存放方式。对于多个元素需要存放在一个变量名下的数据&#xff0c;Python里面常见的有…

MyBatis学习笔记(超详细总结)

MyBatis学习笔记 一、MyBatis概述 1.什么是MyBatis? MyBatis 是一款优秀的持久层框架&#xff0c;用于简化 JDBC 开发 MyBatis 本是 Apache 的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code&#xff0c;并且改名为yBatis 。2013年11…

Docker 搭建java+tomcat

1.  准备java和tomcat的软件包 jdk-7u79-linux-x64.tar.gz apache-tomcat-7.0.57.tar.gz 2.  编辑Dockerfile 文件 vim Dockerfile 1 FROM centos  #基本镜像 2 ADD ./jdk-7u79-linux-x64.tar.gz /root  #将jdk拷贝到镜像的 /root 下 3 ADD ./apache-tomcat-7.0.57.ta…

python发邮件主机找不到_Python 使用QQ邮箱发邮件

QQ邮箱太恶心了。经常改验证方式阿福最近的脚本不能用了&#xff0c;研究了一上午。终于研究出来了。def sendmail(data):content data[content]msg MIMEText(content,_subtypeplain,_charsetutf8)msg[Subject] data[Subject]msg[From] data[From]msg[To] ;.join(data[mail…

创建并发布npm包

1.npm官网创建npm账户 npm网站地址&#xff1a;https://www.npmjs.com/ npm网站注册地址&#xff1a;https://www.npmjs.com/signup 2.命令行工具登录npm npm login 验证登录是否成功 npm who am i 3.创建npm库 npm init 按照提示输入相应内容&#xff1a; 以下为package.json内…

python 文件状态_Python:如何访问文件的状态

一、案例&#xff1a;在某些项目中&#xff0c;需要获取文件的状态文件状态&#xff1a;os.stat(path)1、文件的类型&#xff1a;普通文件、目录、符号链接、设备文件或管道(一般在Linux上)。。。2、文件的访问权限&#xff1a;一般为读、写、执行&#xff0c;3个权限&#xff…

Android 开发笔记___drawable

1 <?xml version"1.0" encoding"utf-8"?>2 <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"3 android:layout_width"match_parent"4 android:layout_height"match_parent"5 …

win7 管理iphone日历_大师给你传授win7系统安装桌面日历的途径

win7正式版系统是公认操作便捷的电脑系统&#xff0c;大概很多人在操作过程中都会有应对win7系统安装桌面日历难题的时候。不少小白计算机技术还纯属于菜鸟&#xff0c;关于win7系统安装桌面日历的情况&#xff0c;不能自行处理。很多人都来询问小编win7系统安装桌面日历应该如…

Ubuntu下gcc多版本共存和版本切换

https://my.oschina.net/u/2306127/blog/538139 摘要: Ubuntu系统使用的gcc版本随着发布版本的不同而不同&#xff0c;在编译android系统时不同的版本推荐用不同的gcc去编译&#xff0c;那么可不可以改变系统的gcc来适应android编译环境的需求呢&#xff1f;答案是可以的。 Ubu…

手动导入maven项目依赖jar包

当通过坐标引入依赖jar包时&#xff0c;经常会出现下载失败或导入失败&#xff0c;需要手动去导入。 通过maven 仓库地址&#xff1a;https://mvnrepository.com/下载或其他方式拷贝的对应依赖jar包到本地。打开cmd命令窗口输入以下命令&#xff1a; mvn install:install-file…

内部属性 聚合_光的本质(用粒子性解释光的所有属性,颜色,介质内速度改变等)...

本文已经发布于《科技展望》2017年27期&#xff0c;转发请注明。1.1 光的本质1.1.1 光的本质光是地球上的生命体存在的前提条件&#xff08;当然地球上也存在不能见光的生命体&#xff0c;但即使是这些生命体不能见光&#xff0c;它们最终需要的能源也间接的来源于光&#xff0…

spring MVC报错:A child container failed during start

严重: A child container failed during start java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Tomcat].StandardHost[localhost].StandardContext[]] at java.util.concurrent.FutureTask.rep…

easyui(一) 初始easyui

分享使我快乐。哈哈~ --WZY 一、什么是easyui&#xff1f; 学习一个东西&#xff0c;最重要的是知道它的定位(是干嘛的&#xff0c;基本的用法是什么&#xff0c;快速入门)&#xff0c;其实easyui也非常简单&#xff0c;不要觉得很难。 easyui就是一个前端框架&#xff0c;JQue…

mysql数据库代码_【代码总结】MYSQL数据库的常见操作

MYSQL数据库的常见操作一、mysql的连接与关闭-h&#xff1a;指定所连接的服务器位置-u&#xff1a;数据库的用户名-p&#xff1a;数据库的密码1 mysql -u 用户名 -p //连接数据库2 密码3 exit //关闭数据库1 mysql_connect($host,$user,$password); //连接数据库2 mysql_close(…