值栈
在页面上能够获取属性值,并不是在请求域中获取,而是从值栈里面获取的。在页面中打印的request实际上是经过struts重新包装的StrutsRequestWrapper
.
StrutsRequestWrapper
类重写了getAttribute方法。
可以从 ActionContext 中获取值栈对象。
属性值是在值栈中获取的,而不是在请求域中获取该属性值。
值栈(ValueStack
)贯穿整个Action的生命周期,每个Action类的对象实例都拥有一个ValueStack
对象,相当于一个数据的中转站,在其中保存当前Action对象和其他相关对象。
ValueStack
对象的内部有两个逻辑部分:
ContextMap
:是个 Map,Struts把各种各样的映射关系(一些Map类型的对象)压入ContextMap
中,实际上就是对ActionContext
的一个引用。Struts会把下面这些映射压入ContextMap
中:
(1)parameters
:该Map中包含当前请求的请求参数
(2)request
:该Map中包含当前request对象中的所有属性
(3)session
:该Map中包含当前session对象中的所有属性
(4)application
:该Map中包含当前application对象中的所有属性
(5)attr
:该Map按如下顺序来检索某个属性:request、session、application
Request、session与application的区别:
- request的setAttribute与getAttribute方法一般都是成对出现的,首先通过setAttribute方法设置属性与属性值,然后通过getAttribute方法根据属性获取得到与该属性对应的对象值(获取得到之后需要进行向下转换,降属性值转换为真正的对象)。两个方法都是在服务器内部执行的,客户端不知道服务器端是否执行过这两个方法。
- request的getParameter方法的作用是获取得到客户端通过表单或URL请求参数所发送过来的参数值,是客户端与服务器之间的交互,服务器端要想获取到客户端发送过来的数据,就需要使用getParameter方法来获取。没有与getParameter方法相对应的setParameter方法。
- request对象内数据的存活范围就是在request对象的存活范围内,当客户端向服务器端发送一个请求,服务器向客户端返回一个响应之后,该请求对象就会被销毁了;之后再向服务器端发送新的请求时,服务器会创建新的request对象,该request对象与之前的request对象没有任何关系,因此也无法获得在之前的request对象中所存放的任何数据。
- session对象内数据的存活范围也就是session对象的存活范围(只要浏览器不关闭,session对象就会一直存在),因为在一个浏览器窗口中,无论向服务器发送多少个请求,session对象只有一个。
- application(应用对象)存活范围最大,只要服务器不关闭,application对象中的数据就会一直存在,在整个服务器运行过程中,application对象只有一个。
- 这三个对象的范围是逐个增加的:request只在一个请求的范围内,session是在浏览器窗口的范围内,application则是在整个服务器的运行过程中。
ObjectStack
:Struts把Action和相关对象压入ObjectStack
。一个使用 ArrayList 定义的栈
OGNL
在JSP页面上可以利用OGNL(图导航语言)访问到值栈里的对象属性。
若访问值栈中 ContextMap
中的数据,需要给OGNL表达式加上一个前缀字符#,如果没有前缀字符#,搜索将在 ObjectStack
里进行。
Struts2 利用 s:property 标签和 OGNL 表达式来读取值栈中的属性值。
-
值栈中的属性值:
- 对于对象栈: 对象栈中某一个对象的属性值
- Map 栈: request, session, application 的一个属性值 或 一个请求参数的值.
-
读取对象栈中对象的属性:
若想访问 Object Stack 里的某个对象的属性. 可以使用以下几种形式之一:
object.propertyName ;
object['propertyName'] ;
object["propertyName"]
结合 s:property 标签:<s:property value="[0].message" /> <s:property value="message" />
为调用message属性。
默认情况下,Action 对象会被 Struts2 自动的放到值栈的栈顶. -
读取Map栈里面对象的属性
可以使用以下几种形式之一:
异常处理
exception-mapping元素
:配置当前action的声明式异常(写在struts.xml中)。
该元素有两个属性:
exception
:指定需要捕获的异常类型,异常的全类名。result
:指定一个响应结果,该结果将在捕获到指定异常时被执行,既可以来自当前action的声明,也可以来自global-results
声明。
可以通过global-exception-mappings
元素为应用程序提供一个全局性的异常捕获映射,但在该元素下声明的任何exception-mapping
元素只能引用在global-results
元素下声明的某个result元素。
声明式异常处理机制由ExceptionMappingInterceptor
拦截器负责处理,当某个exception-mapping
元素声明的异常被捕获到时,ExceptionMappingInterceptor
拦截器就会向ValueStack
中添加两个对象:
exception
:表示被捕获异常的Exception对象exceptionStack
:包含着被捕获异常的栈
可以在视图上通过<s:property>
标签显示异常。
通用标签
property标签
:该标签用来输出一个值栈属性。url标签
:用来动态的创建一个url。param标签
:把一个参数传递给包含着它的那个标签set标签
:用来在Map对象中创建一个键值对push标签
:与set标签类似。该标签将一个对象压入ValueStack而不是压入ContextMap,在标签开始时把一个对象压入栈,标签结束时将对象弹出栈。action标签
:用在页面上来执行一个action。该标签还会把当前Action对象压入ValueStack值栈的ContextMap子栈中。bean标签
:该标签用于创建一个JavaBean,并把它压入ValueStack值栈的ContextMap子栈中。include标签
:用来把一个Servlet或JSP页面的输出包含到当前页面里来。append标签
:用来合并可遍历的对象merge标签
:用来交替合并可遍历对象generator标签
:用来生成一个可遍历对象并将它压入ValueStack栈,该标签结束标记将弹出遍历对象。