在 Struts2中,当一个Action(比如UserAction)将请求跳转(forward)到结果视图(比如result.jsp),有哪些方法可 以将Action的结果带到result.jsp中(即在result.jsp中可以获取到UserAction中的值)?
多种设值方法
1. UserAction的实例字段,只要提供了对应的getter方法,就可以在result.jsp中取到这个值
2. UserAction通过HttpServletRequest的setAttribute方法传值
ServletActionContext.getRequest().setAttribute("key1", "value1");
3. 通过ActionContext.getContext()的put方法,如:
ActionContext.getContext().put(“key1”,“value1”);
4. 通过ActionContext.getContext的ValueStack对象的push方法,如
ValueStack vs = ActionContext.getContext().getValueStack(); vs.setParameter("key1", "value1"); vs.push(new Date());
5. 通过ActionContext.getContext的ValueStack对象的setParameter方法,如
ValueStack vs = ActionContext.getContext().getValueStack(); vs.setParameter("key1", "value1");
6. 通过ActionContext.getContext的ValueStack对象的set方法,如
ValueStack vs = ActionContext.getContext().getValueStack(); vs.set("key1", "value1");
7. 通过ActionContext.getContext的ValueStack对象的setValue方法,如
ValueStack vs = ActionContext.getContext().getValueStack(); vs.setValue("key1", "value1");
问题:
这些API用起来很简单,但是有几个问题需要解决
1.这五种方式之间是否有某种关系,比如,直接往ActionContext中设值,和通过ActionContext往ValueStack中设值有什么区别和联系、
ActionContext.getContext().put(“key1”,“value1”); ValueStack vs = ActionContext.getContext().getValueStack(); vs.setParameter("key1", "value1");
2. 不同方式的设值的优先级,比如都存入一个键为key1的值,那么result.jsp取出时,以哪个值为准
3. 这些不同方式的设值,result.jsp在取出时,是否方式不一样?如果不一样,那么取值表达式的语法是什么?
4.ValueStack,顾名思义,是一个栈结构,也就是Value,先进后出,那么具体的用法是什么?
从Action存放数据的数据结构开始说起
Struts2中, Action相关的数据都存放在ValueStack中,ValueStack分为两部分,ActionContext和Compoud Root
1. ActionContext
a. ActionContext是一个Map数据结构,一方面存放用户通过ActionContext以及ServletActionContext设置的数据(key/value)
b. ActionContext也存放跟http请求相关的对象,比如application,session,request,page,parameters对象
c. 在result.jsp中,使用#属性名的方式告诉Struts,是要到ActionContext中取值,比如<s:property value="#key1"/>
2. CompoundRoot
a.CompoundRoot是一个堆栈数据结构,它继承自ArrayList,同时提供了push,pop等堆栈操作
b.当请求到某个Action时,Struts将这个Action对象放置于栈顶
c.当调用ValueStack的push操作时,会将push的对象放置于栈顶
d.在result.jsp中,使用属性名的方式告诉Struts(不加#),是要到CompoundRoot中取值。取值顺序是从栈顶到栈底依次查找,直到找到匹配给定属性名的属性
e.在result.jsp中,可是用#root[0]指向栈顶元素,使用#root[k]指向从栈顶开始的第k个元素,k从0开始
3. ValueStack的数据结构图
左侧的Object[0--n]以及ValueStack就是CompoundRoot对象的堆栈结构,右侧的ActionContext是一个Map+请求相关的对象(application,session,request,page)
实例
1.struts.xml配置
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <package name="user" namespace="/user" extends="struts-default"> <action name="hi" class="com.tom.actions.UserAction"> <result name="dispatcher" type="dispatcher">/htmls/result.jsp</result> </action> </package> </struts>
2. UserAction
package com.tom.actions; import com.opensymphony.xwork2.ActionContext; import com.tom.model.User; import org.apache.struts2.ServletActionContext; public class UserAction { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String execute() { //通过action属性传值,此时HelloWorldAction位于CompoundRoot栈顶,可以直接获取,不用加# //注意:id属性被后面的ValueStack中的User对象覆盖 //<s:property value="id"/> //<s:property value="name"/> id = 1234; name = "tom"; //通过Context传值,因为是放在Context中,需要使用#访问 //<s:property value="#key1"/> //<s:property value="#key2"/> //<s:property value="#key3"/> ActionContext.getContext().put("key1", "value1"); ActionContext.getContext().put("key2", "value2"); ActionContext.getContext().put("key3", "value3"); //通过ValueStack访问,此时push对象将压栈到CompoundRoot的栈顶,此对象成为根对象 //也就是说,ValueStack的push操作会将对象压到CompundRoot的栈顶 //<s:property value="name"/> //<s:property value="id"/> User user = new User(); user.setId(2345); ActionContext.getContext().getValueStack().push(user); //************************************************************************************************ //此时,CompoundRoot栈包含两个对象,栈顶的User对象以及栈底的UserAction对象 //当通过s:property取值时,是通过从栈顶到栈底的顺序一次查找满足条件的属性,后加入的对象属性将覆盖前面加入的属性 //通过<s:property value="id"/>能取到User对象的id属性,但是取不到UserAction的id属性 //通过<s:property value="#root[1].id"/>能够取到UserAction的id属性,也就是说,通过#root[k]可以取到距离栈顶k个元素的元素 //栈顶为#root[0],其它以此类推 //************************************************************************************************ //通过HttpServletRequest对象传值,因为request放置于context中,所以需要#访问 //<s:property value="#key4"/> ServletActionContext.getRequest().setAttribute("key4", "value4"); //如果栈顶是一个Map,那么将key/value设置到栈顶Map中 //如果栈顶不是一个Map,那么构造一个HashMap,push到栈顶中 // <s:property value="key5"/> User user5 = new User(); user5.setId(5); user5.setName("tom5"); ActionContext.getContext().getValueStack().set("key5", user5); //放置于栈顶Map中 ActionContext.getContext().getValueStack().setParameter("key6", 1000); User user7 = new User(); user7.setId(7); user7.setName("tom7"); //放置于栈顶Map中 ActionContext.getContext().getValueStack().setValue("key7", user7); return "dispatcher"; } }
3. result.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="s" uri="/struts-tags" %> <html> <head> <title></title> </head> <body> key1: <s:property value="#key1"/> <br/> key2: <s:property value="#key2"/> <br/> key3: <s:property value="#key3"/> <br/> id: <s:property value="id"/> <br/> name: <s:property value="#root[1].name"/> <br/> request.key4:<s:property value="#request.key4"/> <br/> key5:<s:property value="key5"/> <br/> key5-2:<s:property value="key5.name"/> <br/> key6:<s:property value="key6"/> <br/> key7:<s:property value="key7.id"/> <br/> top: <s:property value="#root[0]"/> <br/> <s:debug/> </body> </html>
结果
key1: value1 key2: value2 key3: value3 id: 2345 name: request.key4:value4 key5:com.tom.model.User@2fb710a3 key5-2:tom5 key6:1000 key7:7 top: [{key6=1000, key5=com.tom.model.User@2fb710a3, key7=com.tom.model.User@1ba555ce, com.opensymphony.xwork2.util.OgnlValueStack.MAP_IDENTIFIER_KEY=}, com.tom.model.User@3a45590, com.tom.actions.UserAction@19ed62ce, com.opensymphony.xwork2.DefaultTextProvider@2ff1cfae] [Debug] Struts ValueStack Debug Value Stack Contents Object Property Name Property Value java.util.HashMap empty null com.tom.model.User id 2345 name null com.tom.actions.UserAction id 1234 name tom com.opensymphony.xwork2.DefaultTextProvider texts null Stack Context These items are available using the #key notation Key Value com.opensymphony.xwork2.dispatcher.HttpServletRequest org.apache.struts2.dispatcher.StrutsRequestWrapper@751e1ab5 com.opensymphony.xwork2.ActionContext.locale zh_CN com.opensymphony.xwork2.dispatcher.HttpServletResponse HTTP/1.1 200 Content-Type: text/html; charset=utf-8 com.opensymphony.xwork2.ActionContext.name hi com.opensymphony.xwork2.ActionContext.application Exception thrown: java.lang.NullPointerException com.opensymphony.xwork2.ActionContext.conversionErrors {} __component_stack [org.apache.struts2.components.Debug@b6b9d25]
相关推荐
4、 WebWork为每一次请求构建一个ValueStack,并将所有相关的数据对象(例如:Action对象、Model对象等)放到ValueStack中。再将ValueStack暴露给视图页面,这样页面就可以直接访问后台处理生成的数据。 下面我们...
Struts2的核心组件如Action、Result和ValueStack等,它们共同协作以处理用户请求并生成响应。Action是业务逻辑的载体,Result则负责将Action执行后的结果呈现给用户。ValueStack则是一个对象容器,用于在Action与...
第1章 Struts 2:现代Web框架 2 1.1 Web应用程序:快速学习 2 1.1.1 构建Web应用程序 2 1.1.2 基础技术简介 3 1.1.3 深入研究 6 1.2 Web应用程序框架 7 1.2.1 什么是框架 7 1.2.2 为什么使用框架 8 1.3 Struts 2框架...
Action是Struts2的核心组件,用于处理用户的请求,并返回相应的结果。在现代Web应用中,数据通常以JSON(JavaScript Object Notation)格式在客户端和服务器之间交换,因为JSON具有轻量级、易于解析的特性。本篇将...
Struts 2的ValueStack机制使得模型数据可以直接在视图层访问,无需显式传递。 对于表单处理,Struts 2提供了强大的支持。它能够自动绑定表单字段到Action属性,处理验证逻辑,并且可以方便地实现回滚和重定向。此外...
在模型层方面,《Struts2 in Action》讲解了如何将业务逻辑集成到Struts2框架中,包括使用ActionSupport基类、ModelDriven接口以及ValueStack等特性。书中还会介绍如何与持久层框架如Hibernate或MyBatis进行集成,...
- **Struts2**: 引入了ValueStack的概念,这使得开发者可以在视图层直接访问Action中的数据。Struts2还支持多种视图技术,如FreeMarker、Velocity等。 #### 数据绑定 - **Struts1**: 使用Commons-BeanUtils进行...
Struts2是一个基于MVC设计模式的Web应用框架,它起源于WebWork2,并...对于初学者而言,快速掌握Struts2的关键在于理解其核心概念,如Action、配置文件、OGNL和ValueStack,以及如何利用这些特性来构建高效的Web应用。
在项目中使用Struts2时,我们需要配置struts2的主配置文件(struts.xml),定义Action、结果类型、拦截器栈等。Action是业务逻辑的入口点,Result表示一个操作完成后转向的页面或结果。拦截器是Struts2的一大特色,...
Action类通常继承自`org.struts2.StrutsAction`或实现`com.opensymphony.xwork2.Action`接口。 3. **配置文件**:Struts2使用XML配置文件(struts.xml)来定义Action及其关联的Action方法、结果页面等,提供了一种...
OgnlValueStack stack = (OgnlValueStack) request.get("struts.valueStack"); HttpServletResponse response = (HttpServletResponse) stack.findValue("response"); // 使用 response 对象 } } ``` 方法 3:...
在 Struts2 接收到一个.action 的请求后,会先建立 Action 类的对象实例,但并不会调用 Action 方法,而是先将 Action 类的相应属性放到 ValueStack 对象的顶层节点中。 ValueStack 对象相当于一个栈,存放着当前...
视图层的绑定方面,Struts1依赖标准JSP机制,而Struts2引入了ValueStack技术,使得taglib可以直接访问值栈中的对象,无需在视图层与对象进行一对一绑定,提高了代码的复用性。 类型转换上,Struts1使用Apache ...
ValueStack是Struts2的核心组件之一,它是一个数据存储结构,用于管理Action上下文中的对象。Action中的属性会被放入ValueStack,从而可以直接在JSP中通过OGNL表达式访问。 8. **ValueStack Debug和Contents** ...
在Struts2框架中,ActionError和ActionMessage是处理用户输入验证和错误反馈的重要组件,它们使得开发者能够优雅地管理应用程序中的错误信息和用户消息。 ActionError类是用来存储错误信息的,它继承自`java.lang....
- **Action类**: Struts2的核心是Action类,它是业务逻辑的载体。开发者通常会创建一个Action类来处理用户请求,并通过execute方法执行相应的业务逻辑。 - **配置文件**: Struts2的配置文件通常包括struts.xml,...
本文将深入探讨Struts2的核心概念,包括Action、Result、配置文件、OGNL与ValueStack、Tags以及项目中的关键实践。 **一、Action** Action是Struts2中处理业务逻辑的核心组件,它是实现了`...
此外,Struts2还提供了一个强大的ValueStack机制,用于在Action和视图之间传递数据。 #### 六、配置机制的不同 - **Struts1**: 使用XML配置文件进行配置,这种方式虽然直观但随着项目规模的增长可能会变得难以管理...