Struts2 中的值栈的理解
- 格式:pdf
- 大小:92.79 KB
- 文档页数:2
1. 数据传输背后机制:ValueStack(值栈)在这一切的背后,是因为有了ValueStack(值栈)!ValueStack基础:OGNL要了解ValueStack,必须先理解OGNL(Object Graphic Navigatino Language)!OGNL是Struts2中使用的一种表达式语言,它可以用于JSP的标签库中,以便能够方便的访问各种对象的属性;它用于界面将参数传递到Action(并进行类型转换)中;它还可以用于struts2的配置文件中!所以,非常有必要理解OGNL的基本机制。
Root对象OGNL称为对象图导航语言。
所谓对象图,即以任意一个对象为根,通过OGNL可以访问与这个对象关联的其它对象。
如:package .leadfar.struts2.actions;public class User {private String username;private Group group;public String getUsername() {return username;}public void setUsername(String username) {ername = username;}public Group getGroup() {return group;}public void setGroup(Group group) {this.group = group;}}package .leadfar.struts2.actions;public class Group {private String name;private Organization org;public String getName() {return name;}public void setName(String name) { = name;}public Organization getOrg() {return org;}public void setOrg(Organization org) { = org;}}package .leadfar.struts2.actions;public class Organization {private String orgId;public String getOrgId() {return orgId;}public void setOrgId(String orgId) {Id = orgId;}}上面三个类,描述了通过一个User对象,可以导航到Group对象,进而导航到Organization对象,以User对象为根,一个对象图如下所示:User(root)-- username-- group-- name-- org-- orgId在真实的环境下,这个对象图可能会极其复杂,但是通过基本的getters方法,都应该能够访问到某个对象的其它关联对象。
OGNL:【struts的标签库在 struts2-core-2.3.11.jar 下的META-INF下】【引入标签库:<%@ taglib uri="/struts-tags" prefix="s"%>】OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目。
Struts2框架使用OGNL作为默认的表达式语言。
OGNL相对其它表达式语言具有下面几大优势:1、支持对象方法调用,如xxx.doSomeSpecial();2、支持类静态的方法调用和值访问,表达式的格式:@[类全名(包括包路径)]@[方法名 | ?值名],例如:@ng.String@format('foo %s', 'bar')或@tutorial.MyConstant@APP_NAME;3、支持赋值操作和表达式串联,如price=100, discount=0.8,calculatePrice(),这个表达式会返回80;4、访问OGNL上下文(OGNL context)和ActionContext;5、操作集合对象。
Ognl 有一个上下文(Context)概念,说白了上下文就是一个MAP结构,它实现了java.utils.Map的接口.OGNL(Object Graph Navigation Language),是一种表达式语言。
使用这种表达式语言,你可以通过某种表达式语法,存取Java对象树中的任意属性、调用Java对象树的方法、同时能够自动实现必要的类型转化。
如果我们把表达式看做是一个带有语义的字符串,那么OGNL无疑成为了这个语义字符串与Java对象之间沟通的桥梁。
================================================================================ ====================================================【一、理解Struts2中的 ValueStack:】ValueStack实际是一个接口,在Struts2中利用OGNL时,实际上使用的是实现了该接口的OgnlValueStack类,这个类是Struts2利用OGNL的基础ValueStack(值栈): 贯穿整个 Action 的生命周期(每个 Action 类的对象实例都拥有一个ValueStack 对象). 相当于一个数据的中转站. 在其中保存当前Action 对象和其他相关对象.Struts 框架把 ValueStack 对象保存在名为“struts.valueStack”的请求属性中,request 中在 ValueStack 对象的内部有两个逻辑部分:ObjectStack: Struts 把动作和相关对象压入 ObjectStack 中--List 对象栈ContextMap: Struts 把各种各样的映射关系(一些 Map 类型的对象) 压入 ContextMap 中Map栈Struts 会把下面这些映射压入 ContextMap 中 (Map栈中)root: ObjectStack对象栈的引用parameters: 该 Map 中包含当前请求的请求参数request: 该 Map 中包含当前 request 对象中的所有属性session: 该 Map 中包含当前 session 对象中的所有属性application:该 Map 中包含当前 application 对象中的所有属性attr: 该 Map 按如下顺序来检索某个属性: request, session, application在ObjectStack(对象栈)中一般放入:ValueStackAction对象map集合实体类对象================================================================================ =======================================【二、理解OGNL Context】OgnlValueStack 类包含两个重要的属性一个root和一个context。
Struts2 框架第三天今天重点内容安排:第一天:struts2 开发流程、访问Action,Action方法调用,结果集类型第二天:获取请求参数,请求数据校验机制,拦截器1、V alueStack 值栈的存储原理和相关操作2、Ognl 表达式语言语法3、struts2 页面控制标签4、struts2 form表单相关标签重点难点:值栈和Ognl1.值栈和Ognl表达式1.1.什么是OgnlOgnl 对象导航图语言Object Graphic Navigation Language,类似EL,比EL ${}语法要强大很多,Struts2框架使用OGNL作为默认的表达式语言必须要引入struts标签库EL Expression Language 表达式语言,用来获取JSP页面四个域范围数据pageContext、request、session、application )Ognl 主要用法:1、访问OGNL上下文值栈对象获取数据(最重要)2、操作集合对象(结合struts2 标签库使用)---- 生成checkbox 、生成select 1.2.什么是值栈ValueStack接口!值栈ValueStack 实际上是一个接口,struts2 Ognl使用都是基于值栈完成的Struts2 内部提供OgnlValueStack的接口实现类,实现了值栈接口!前端控制器每一次请求都会创建一个值栈对象源码:一次请求对应一个值栈对象值栈生命周期= request 生命周期的!!值栈是struts2 一个数据结构,贯穿整个Action实例生命周期(request生命周期),一次请求对应一个Action实例,一个Action实例对应一个值栈实例值栈保存了Action 和其它常用web对象的引用,通过值栈,间接操作这些对象!1.3.值栈的存储结构1:采用标签<s:debug>查看值栈结构图:map Context 结构图2:采用degbug模式查看值栈重要的两个部分结构如图所示:得出结论:值栈包含两个部分:root map⏹CompoundRoot对象,保存Action相关对象--- List结构⏹ContextMap 上下文Map,保存常用web对象引用---- Map结构值栈对象获取两种方式:可以由源码追踪得到:如图:1、request.getAttribute(“struts.valueStack”);2、ActionContext.getContext().getValueStack() ;值栈包括CompoundRoot (对象栈,继承ArrayList)、OgnlContext (ognl上下文,实现Map接口)OgnlContext 上下文,引入CompoundRoot,提供HashMap (values),引用常用web对象1.4.详细分析值栈内部对象的创建和生命周期值栈生命周期,就是request生命周期,一次请求,对应一个值栈实例每次新的请求对应一个新的值栈对象实例! 源码:值栈创建过程源码分析:如果请求资源是jsp静态页面而非action 值栈对象也创建:但是拦截器不起作用!如果访问的是action组件需要注意拦截器会起作用生效!!1、在StrutsPrepareAndExecuteFilter的prepare.createActionContext(request, response);创建ValueStack ,将常用web对象,保存OgnlContext的Map 中2、访问Action ,通过ActionProxy ,调用ActionInvocationDefaultActionInvocation 的init 方法stack.push(action); 将当前Action对象,压入root栈顶部V alueStack 的root 栈存在2个对象,DefaultTextProvider、ValueStackAction(Action栈顶)3、执行ModelDriven 拦截器,判断Action是否实现ModelDriven接口,如果实现了,stack.push(model); 将model压入root栈顶部,root栈三个对象1.5.ognl表达式会执行ValueStack 的findValue 搜索值栈中数据搜索顺序,先搜索Root栈每个对象的属性,如果都没有搜索Map的key直接搜索Map的key ,不会搜索root栈⏹如果访问root (CompoundRoot 对象栈内容),不需要#⏹如果访问Map 内容(request、response、session、servletContext、attr、parameters),⏹需要# 进行访问例如# 相当于request.getAttribute(“name” )1.6.案例演示:值栈存储数据和ognl获取数据1.6.1.值栈中保存基本数据类型(int double String) action 存储数据m1.jsp 获取数据2: 采用set 方法压入栈顶action 代码m2.jsp 页面获取之3: 数据存放在context map 值栈下方数据action 代码:m3.jsp1.6.2.值栈中保存对象数据类型action 存储对象因action 存放值栈对象中所以提供成员对象通过值栈存储页面获取相关数据对象存储除了栈顶之外栈顶对象: 通过属性名获取值!!非栈顶对象valuestack.find(搜索表达式); action 代码m4.jsp页面获取数据1.6.3.值栈中保存集合数据类型(list /map)迭代list集合action代码压入值栈list_map.jsp 页面迭代map存入值栈迭代数组action代码压入值栈页面迭代数据1.6.4.值栈中保存web相关的数据类型用户数据保存request session.....jsp 页面获取这些对象中保存数据通过下方context 对象#key #parameters : 获取请求参数信息request.getParameterMap()=#parameters <,String[]>demo1:#attr 搜索pageContext request valuestack session application 类型EL 按照顺序查找存储数据添加值栈!! attr 搜索的顺序如果上述对象搜索完毕都没有需要数据返回Null 如果找到不找了!!demo2#request request 存储数据demo3#session session 存储demo4action 代码:m6.jsp页面获取相关数据1.6.5.ognl之#号的使用用法一:访问OgnlContext的Map中常用web对象,添加#进行访问#attr 按照page --- request --- session --- application进行搜索Action 代码Jsp代码用法二:不加# 调用ValueStack搜索,先搜索root属性,后搜索Map Action 代码JSP代码用法3:构造Map#{…foo1‟:…bar1‟, …foo2‟:…bar2‟}相当于Map集合对象构造List集合{"睡觉","跑步","洗衣服"}例如:1.7.EL表示式也可以获取值栈数据EL 表达式原理,在pageContext、request、session、application 四个范围,调用request.getAttribute() 获取数据EL可以获取值栈数据引入struts2前端控制器改写request.getAttribute() request 对象做了一个包装重写request.getAttribute() 原来request.getAttribute() 直接从request.setAttribute(存储) 获取数据现在: struts2 getAttribute() 重写: 先去request.getAttribute(key) 找到返回!! 如果找不到返回值null 根据null 继续搜索值栈调用值栈对象findValue(expression) 如果找不到Null 找到返回request 产生变异getAttribute() EL搜索顺序pageContext、request、valueStack session、application阅读StrutsPrepareAndExecuteFilter 源码对requestStruts2 框架提供StrutsRequestWrapper 包装类,对request 的getAttribute 方法增强优先使用request.getAttribute 取值,如果取不到,执行valueStack的findValue方法当堂问题:request.setAttribute(“name“, ”aaa“ ) ;valueStack.set(“name“,”bbb“ )页面<s:property name=”name” /> ----- bbb${name} ------ aaa2.Ognl 表达式语法Struts2 存取数据,通过值栈完成的,Ognl 是访问值栈数据表示式语言语法:% 号用法$ 号用法2.1.%号的使用(jsp页面或者配置struts.xml)“%”符号的用途是在标签的属性值被理解为字符串类型时,告诉执行环境%{}里的是OGNL表达式。
Struts2框架的原理和应用1. 什么是Struts2框架Struts2是一个基于Java EE的开源Web应用框架,是Struts框架的升级版。
它通过MVC设计模式实现了Web应用开发的分层,将业务逻辑、数据模型和用户界面分离,使得代码更加清晰、易于维护。
2. Struts2框架的原理Struts2框架的原理主要包括以下几个关键点:MVC设计模式Struts2采用了MVC(Model-View-Controller)设计模式,其中:•模型(Model):负责管理应用程序的数据和业务逻辑。
•视图(View):负责显示数据给用户。
•控制器(Controller):负责处理用户输入、调用模型和视图等。
核心组件Struts2框架包含以下核心组件:•拦截器(Interceptor):负责在请求前后进行统一处理,可以用来进行身份验证、日志记录等操作。
•动作(Action):负责处理用户请求,包括接收请求参数、调用业务逻辑方法等。
•结果(Result):负责生成并返回视图,可以是JSP、Freemarker、JSON等。
•值栈(ValueStack):用于存储Action处理过程中的数据,支持OGNL表达式读取和赋值操作。
•配置文件(struts.xml):用于配置拦截器、动作、结果等,实现URL与处理类之间的映射关系。
工作流程Struts2框架的工作流程如下:1.客户端发送请求到Struts2框架的前端控制器(例如:DispatcherFilter)。
2.前端控制器根据请求的URL找到对应的处理类(Action)。
3.前端控制器将请求参数、上下文信息等传递给Action,同时执行拦截器的前置处理逻辑。
4.Action处理用户请求,并根据业务逻辑生成相应的结果。
5.前端控制器将结果传递给结果组件,选择合适的视图进行渲染。
6.前端控制器将渲染后的视图返回给客户端。
3. Struts2框架的应用Struts2框架在Web应用开发中具有广泛的应用,以下是一些主要的应用场景:1. 构建Web应用程序Struts2框架提供了许多构建Web应用程序的工具和技术,包括表单验证、国际化、文件上传等功能。
Struts 2的基本流程Struts 2框架由3个部分组成:核心控制器FilterDispatcher、业务控制器和用户实现的业务逻辑组件。
在这3个部分里,Struts 2框架提供了核心控制器FilterDispatcher,而用户需要实现业务控制器和业务逻辑组件。
2.核心控制器:FilterDispatcherFilterDispatcher是Struts 2框架的核心控制器,该控制器作为一个Filter运行在Web应用中,它负责拦截所有的用户请求,当用户请求到达时,该Filter会过滤用户请求。
如果用户请求以action结尾,该请求将被转入Struts 2框架处理。
Struts 2框架获得了*.action请求后,将根据*.action请求的前面部分决定调用哪个业务逻辑组件,例如,对于login.action请求,Struts 2调用名为login的Action来处理该请求。
Struts 2应用中的Action都被定义在struts.xml文件中,在该文件中定义Action时,定义了该Action的name属性和class属性,其中name属性决定了该Action处理哪个用户请求,而class属性决定了该Action的实现类。
Struts 2用于处理用户请求的Action实例,并不是用户实现的业务控制器,而是Action代理——因为用户实现的业务控制器并没有与Servlet API耦合,显然无法处理用户请求。
而Struts 2框架提供了系列拦截器,该系列拦截器负责将HttpServletRequest请求中的请求参数解析出来,传入到Action中,并回调Action 的execute方法来处理用户请求。
显然,上面的处理过程是典型的AOP(面向切面编程)处理方式。
图3.19显示了这种处理模型。
图3.19 Struts 2的拦截器和Action从图3.19中可以看出,用户实现的Action类仅仅是Struts 2的Action代理的代理目标。
struts2的工作原理Struts2是一个基于Java的开源Web应用程序框架,用于快速构建企业级Web应用程序。
它采用了模型-视图-控制器(MVC)架构模式,通过统一的控制器来处理用户的请求,并将结果返回给视图进行展示。
本文将介绍Struts2的工作原理,包括请求的处理流程、组件的作用以及如何配置和使用Struts2。
一、Struts2的请求处理流程1. 客户端发送HTTP请求到服务器。
2. 服务器接收到请求后,将请求交给Struts2的过滤器(StrutsPrepareAndExecuteFilter)进行处理。
3. 过滤器根据请求的URL找到对应的Action,并将请求参数封装到Action的属性中。
4. 过滤器调用Action的execute()方法进行业务逻辑处理。
5. Action执行完毕后,返回一个结果视图。
6. 过滤器根据结果视图的配置,将结果返回给客户端。
二、Struts2的组件作用1. Action:Action是Struts2框架的核心组件,用于处理用户的请求。
每个Action类对应一个业务功能,其中的方法对应不同的请求处理逻辑。
2. Interceptor:Interceptor是Struts2框架的拦截器,用于在Action执行前后进行一些额外的处理。
例如,可以在Interceptor中进行身份验证、日志记录等操作。
3. Result:Result是Struts2框架的结果视图,用于将Action的处理结果展示给用户。
可以配置不同的Result类型,如跳转到指定页面、返回JSON数据等。
4. ValueStack:ValueStack是Struts2框架的数据栈,用于存储Action中的属性。
在页面中可以通过表达式语言访问ValueStack 中的数据。
三、Struts2的配置和使用1. 配置文件:Struts2的配置文件是struts.xml,用于配置Action、Interceptor、Result等组件的相关属性。
《企业级应用开发》实验报告
Struts2标签库、OGNL表达式和值栈
一、实验目的
学会使用struts2框架。
二、实验环境
Windows10操作系统,谷歌浏览器,IDEA2019。
三、实验内容与实验过程及分析(写出详细的实验步骤,并分析实验结果)
实验:使用struts2框架搭建视图层步骤:
配置文件struts.xml,与之前的配置区别是加入了控制模板主题的属性
“struts.ui.theme”,xhtml为struts2的默认主题,开启访问静态方法的支持:
web.xml配置文件只需配置strut2框架所需的过滤器即可。
UserLoginAction和UserRegisterAction分别是管理用户的登录和注册,前一个使用字段驱动(验证登录的只需要两个属性),后一个使用模型驱动。
两个主要的jsp运用struts2的标签库。
登录:
注册:
利用值栈显示模型驱动的信息
实验结果图为:登录:
注册:
ognl:
访问静态属性和方法:
值栈:
四、实验总结(每项不少于20字)
存在问题:代码书写不够熟练,关于配置struts.xml进行操作还有许多不足的地方。
解决方法:回忆老师讲的内容,反复调试,经过多次尝试各大属性的作用。
收获:要打好基础,脚踏实地,认真钻研。
五、教师批语。
变某个属性值后,Action类的相应属性值就会变成在拦截器中最后改变该属性 的这个值。
从上面的描述很容易知道,在Struts 2的的Action类可以获得与属性同名的参数值就是通过不同的拦截器来处理的,如获得请求参数的拦截器是params,获得Action的配置参数的拦截器是staticParams等。
在这些拦截器内部读取相应的值,并更新ValueStack对象顶层节点的相应属性的值。
而ValueStack对象 就象一个传送带,将属性值从一个拦截器传到了另一个拦截器(当然,在这其间,属性值可能改变),最后会传到Action对象,并将ValueStack对 象中的属性的值终值赋给Action类的相应属性。