标签:
在这里我要说一下在action中怎么向页面传值~在action中依然可以像以前在servlet里面一样,使用request、session、application向页面传送值,除此之外,action里面还有俩个独有的传值方式:ValueStack ActionContext
一,先来说说这俩个独有的传值方式~
1.ValueStack的特点(值栈):
1.把一个对象放到vs里面之后,我们从这个vs中是拿不到这个对象的,但是我们可以直接拿到这个对象里面的属性以及属性值.
2.从vs中拿值的时候,是从vs中的property name这一个列来拿的,拿到的是property value这一列的值.(在debug中的vs视图可以看这些列)
所以如果我们通过vs把一个值传到页面,我们不能直接把这个值放到vs里,因为这样拿不到,我们应该把这个值放到一个对象的属性里面,然后再把这个对象放vs中,这个时候就可以通过vs拿到这个对象的属性了,也就是我们要传的值.
3.每次浏览器发送一个新的请求,都会生成一个新的ValueStack对象,上一次的ValueStack对象就没了,找不到了.(类似之前学习的request对象的特点)
4.每次创建一个新的ValueStack对象后,会把这个对象放到ActionContext里面.
2.ActionContext的特点
1.向ac里面放值的时候是通过key-value的形式存放的,key是String类型,value是Object类型,取值的是同样通过key拿到value.
2.struts框架默认向这个对象里面存放的对象(数据)很多,包括request、session、application、ValueStack、parameters等
3.每次请求都会创建一个新的ActionContext对象(每次请求打印出ac的地址值可以看出来)
接下来就代码编写~
第一步:
ValueStack是一个接口:com.opensymphony.xwork2.util.ValueStack
ActionContext是一个类:com.opensymphony.xwork2.ActionContext
我们可以使用这个俩个类型的对象,从action里面把值带到页面.
代码编写如下:ValueStackAction类
public class ValueStackAction extends ActionSupport{ private static final long serialVersionUID = 1L; public String execute(){ //测试action,ValueStack, ActionContext context=ActionContext.getContext(); ValueStack stack=context.getValueStack(); System.out.println("action:"+this); System.out.println("context:"+context); System.out.println("stack:"+stack); return SUCCESS; } }
第二步:
我们在页面中,可以通过一个struts2的标签来看到action传到页面中的值:
<s:debug/>
页面引入标签库:<%@taglib uri="/struts-tags" prefix="s" %>
代码如下:在页面index.jsp中写标签~
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <span style="color:#ff0000;"><%@taglib uri="/struts-tags" prefix="s"%></span> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>index.jsp</title> </head>
<body> <h4>index.jsp</h4> <span style="color:#ff0000;"><s:debug></s:debug> </span> </body>第三步:
当前action进行跳转的时候,struts2框架会自动的把当这个action对象本身分别放到ValueStack和ActionContext这个俩个对象,然后struts2框架再把这个俩个对象传给页面,所以我们在页面中只要通过这个俩个对象,就可以拿到之前放进去的值.(在页面的debug标签中,可以看到struts框架放到这俩个对象里面的action)
配置文件struts.xml配置这个Action:
<action name="vs" class="com.xu.struts2.web.action.ValueStackAction"> <result name="success" >/WEB-INF/jsp/index.jsp</result> </action>在浏览器中输入localhost:9999/Struts2/vs.action,效果图如下:
第四步:
除了struts框架自动的像ValueStack和ActionContext里面放值以外,我们还可以手动的向这俩个对象里面放值.
(在execute方法中拿到这个俩个对象就可以向里面放值了)
代码如下:
ValueStackAction类--get和set方法一定要写
public class ValueStackAction extends ActionSupport{ private String name; private int age; private Boolean gender; private static final long serialVersionUID = 1L; public String execute(){ //测试action,ValueStack, name="tee"; age=12; gender=true; ActionContext context=ActionContext.getContext(); ValueStack stack=context.getValueStack(); System.out.println("action:"+this); System.out.println("context:"+context); System.out.println("stack:"+stack); return SUCCESS; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Boolean getGender() { return gender; } public void setGender(Boolean gender) { this.gender = gender; } }页面index.jsp也要添加几行代码,用到了EL表达式~
<body> <h4>index.jsp</h4> <hr> name:${name } <br> age:${age } <br> gender:${gender }<br> <hr> <s:debug></s:debug> </body>效果图如下:
第五步:
向ac和vs中主动放值
向ActionContext对象中放值:
context.put(String,Object);
context.put("hello","world");
向ValueStack对象中放值:
User user = new User();
stack.push(user);
只是需要改写ValueStack~,代码如下:
public class ValueStackAction extends ActionSupport{ private String name; private int age; private Boolean gender; private static final long serialVersionUID = 1L; private User user; public String execute(){ //测试action,ValueStack, name="tee"; age=12; gender=true; user=new User(1L, "larr", 12, false, "123"); ActionContext context=ActionContext.getContext(); ValueStack stack=context.getValueStack(); context.put("hello", "world"); stack.push(user);//手动把user对象放入值桟 System.out.println("action:"+this); System.out.println("context:"+context); System.out.println("stack:"+stack); return SUCCESS; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Boolean getGender() { return gender; } public void setGender(Boolean gender) { this.gender = gender; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } }效果图如下:
注意:使用vs和ac传值的时候,要使用服务器内部跳转的方式.
总结:
客户端发送一个请求到action,struts2框架会创建俩个对象:ValueStack对象和ActionContext对象,action执行完进行跳转的的同时,struts2框架会这个当前执行的action对象分别放到ValueStack对象和ActionContext对象里面,在页面中通过debug标签可以到放到这俩个对象里面的action对象.所以最终我们在页面就可以通过ValueStack对象或者ActionContext对象拿到action里面的属性值(get/set方法)
二,再来说说在action中访问web元素(request session application)
1.在struts2框架中,这三个对象分别都有俩个类型:原类型和Map类型(这个对象都在ActionContext里面)
2.原类型: (指的就是之前在servlet中使用的对象类型)
HttpServletRequest request
HttpSession session
ServletContext application
Map类型:
Map<String,Object> request
Map<String,Object> session
Map<String,Object> application
3.在使用的时候,我们可以选择使用原类型的request或者选择使用Map类型的request.(session和application也是这样的情况)
4.不管是原类型的还是Map类型的对象,都是被struts2框架默认存放到了ActionContext对象里面.(使用debug标签可以看到)
5.原类型的和Map类型的关系.
Map<String,Object> session1 = ActionContext.getContext().getSession();
HttpSession session2 = ServletActionContext.getRequest().getSession();
a.使用Map类型的对象,可以降低代码中对 servlet的API的依赖(降耦)
b.我们使用原类型大多时候也是存值和取值,
而且原类型里面本身也是封装了Map对象。
所以我们使用Map类型的对象也可以完成存值和取值.
c.Map类型的request对象里面的值(k-v),其实就是复制的原类型的
request对象里面的值(k-v),当然原类型的request对象里面除了k-v类型的键值对以外,
还有其他的属性和方法,因为它毕竟是HttpServletRequest类型的对象.
d.所以原类型的request和Map类型的request对象,我们可以理解为他们里面的值(k-v)是相通的,相通的意思就是:这个对象里面有什么值,那个对象里就也
会什么值.所以我们在action里面向Map类型的对象中存放一个值(k-v),将来在页面中同样是可以使用原类型的request对象那这个值(k-v)取出来的.
注:session和application的情况也是一样的道理.
原类型和Map类型相当于下面这个例子:
张三手里有一个钱包,我们平时都是把钱给张三,张三再把钱放到钱包里面, 我们拿钱的时候也是通过张三,张三从钱包里拿出钱,然后再把钱给我们.现在我们不想这么做,觉得很麻烦,我们直接从张三手里抢过来这个钱包,我们存钱和拿钱都直接操作这个钱包原类型的request就相当于这里的张三,Map类型对象就相当于这个钱包
接下来就代码编写~
第一步:
获取Map类型对象
第一种方式:自己在方法中主动获得
ActionContext ac = ActionContext.getContext(); //获得Map类型request Map<String,Object> request = (Map<String, Object>) ac.get("request"); //获得Map类型session Map<String, Object> session = ac.getSession(); //获得Map类型application Map<String, Object> application = ac.getApplication();第二种方式:让struts2框架把Map类型的对象自动的放到action里(依赖注入)
第一种方式-主动方式~
代码如下:
WebAction:
public class WebAction extends ActionSupport { private static final long serialVersionUID = 1L; @Override public String execute() throws Exception { //主动 ActionContext context=ActionContext.getContext(); //ServletContext 实际存放值的地方 Map<String,Object>application=context.getApplication(); //HttpSession实际存放值的地方 Map<String, Object>session=context.getSession(); session.put("sessionKey", "sessionValue..."); application.put("applicationKey", "applicationValue..."); return SUCCESS; } }在struts.xml要配置这个action,代码如下:
<action name="web" class="com.xu.struts2.web.action.WebAction"> <result name="success" >/WEB-INF/jsp/index.jsp</result> </action>
<body> <h4>index.jsp</h4> <hr> session:${sessionScope.sessionKey }<br> application:${applicationScope.applicationKey }<br> <hr> </body>在浏览器中输入localhost:9999/Struts/web.action,效果图如下:
第二种方式-被动方式~
代码如下:
WebAction类:
public class WebAction extends ActionSupport implements RequestAware,SessionAware,ApplicationAware{ private static final long serialVersionUID = 1L; private Map<String, Object> request; private Map<String, Object> session; private Map<String, Object> application; @Override public String execute() throws Exception { //页面中用原类型的对象去正常值就可以了 request.put("MyName", "tom"); session.put("YourName", "zhansan"); application.put("HerName", "lily"); return SUCCESS; } public void setRequest(Map<String, Object> request) { this.request = request; } public void setSession(Map<String, Object> session) { this.session = session; } public void setApplication(Map<String, Object> application) { this.application = application; } }
在index.jsp要接收从action传来的值,代码如下:
<body> <h4>index.jsp</h4> <hr> request:${requestScope.MyName }<br> session:${sessionScope.YourName }<br> application:${applicationScope.HerName }<br> <hr> </body>效果图如下:
第二步:
获取原类型对象
第一种方式:自己主动获得
获得原类型request对象
HttpServletRequest req = ServletActionContext.getRequest();
获得原类型response对象
HttpServletResponse res = ServletActionContext.getResponse();
获得原类型session对象
HttpSession sess = req.getSession();
获得原类型application对象
ServletContext app1 = sess.getServletContext();
或者
ServletContext app2 = ServletActionContext.getServletContext();
第二种方式:自己被动接收
struts2框架中提供了一个接口,可以用来获得原类型的request对象,
因为通过原类型的request对象就可以获得原类型的session对象和原
类型的application对象
实现接口:ServletRequestAware,然后struts2框架会通过action所实现的抽象方法,把原类型的request对象自动放到action里面.
类似的还有一接口:ServletResponseAware,和上面的效果、用法是一样的。
代码编写如下:
第一种方式-主动获得~
Web2Action类:
public class Web2Action extends ActionSupport { public String execute(){ //主动获取 ServletContext s_application=ServletActionContext.getServletContext(); HttpServletRequest s_request=ServletActionContext.getRequest(); HttpSession s_session=s_request.getSession(); s_application.setAttribute("application", "zhangsan"); s_request.setAttribute("request", "lili"); return SUCCESS; } }在struts.xml配置这个action:
<action name="web2" class="com.xu.struts2.web.action.Web2Action"> <result name="success" >/WEB-INF/jsp/index.jsp</result> </action>在页面index.jsp接收这个参数:
<body> <h4>index.jsp</h4> <hr> request:${requestScope.request }<br> session:${sessionScope.session }<br> application:${applicationScope.application }<br> <hr> </body>在浏览器中输入localhost:9999/Struts2/web2.action
效果图如下:
第二种方式-被动方式~
实现接口
代码如下:
Web2Action类:
public class Web2Action extends ActionSupport implements ServletRequestAware,ServletContextAware{ private HttpServletRequest request; private ServletContext application; public String execute(){ //被动获取 HttpSession session=request.getSession(); request.setAttribute("request", "00requsetKey00"); session.setAttribute("session","00sessionKey00"); application.setAttribute("application", "00applicationKey00"); return SUCCESS; } @Override public void setServletRequest(HttpServletRequest request) { // TODO Auto-generated method stub this.request=request; } @Override public void setServletContext(ServletContext application) { // TODO Auto-generated method stub this.application=application; } }别的什么都不变~
效果图如下:
好了,到这里action向页面传值就写完了~
有什么疑问的可以问我~
标签:
原文地址:http://blog.csdn.net/qq_33642117/article/details/51914643