最近,看到一些写Struts引渡参数的博客,我实在忍不住想做这篇博客,因为我觉得,Struts的值的引渡,不应该是那样的,虽然我自从用了springmvc之后,被springmvc的强大魅力所吸引而不能自拔,但是我也不愿看到Struts不地道的使用!
首先说Struts,我们不可否认,Struts有两个核心概念,可以说这两个核心概念是Struts的灵魂,一个叫做值栈(ValueStack),一个叫做作用域(Action Scope)
下面先说值栈,第一点,值栈的生命周期,值栈的生命周期是多少呢?是一次请求,说到这里有没有觉得它和一个东西很像呢?request对吧,request的生命周期是不是一次请求有效呢?
如此生命周期算是说完了,为下面的讨论埋下伏笔!
第二,就是值栈当中有4个内置map对象,分别是request,session,application还有一个忘了,可能就3个,但是我记得是4个,因为前面说了,好久没用了,记不清了,不过不影响!此也为后面讨论埋下伏笔.
下面我们再说下作用域,request,一次请求有效,session作用域是什么呢?谁能告诉我?我觉得很多人对session作用域的范围不是很了解,浏览器关了,session不起作用,但是他的生命周期结束了么?这个session真的就不能用了么?我要说的是:非也!浏览器关了,session的生命周期并没有结束,我们可以用各种手段拿到之前的session,让他重为我所用!因为虽然你客户端是没有session了,但是服务器还有,服务器还有session的存档,我只需要知道jsessionid我就可以拿到session!好这个问题不再说,第三个application,作用范围是一个应用内有效,声明周期随服务器的生命周期,别的不多说,我们今天的核心是requst,
前面说了request和ValueStack的生命周期一样,既然如此,为什么我们不用值栈来替换request呢?既然你们的作用范围一样,生命周期一样,那么,对于数据的传递,是不是就可以完全替代呢?所以,这里就说的是Struts传值的高级用法,用值栈代替request,废话少说直接上代码:
// 定义实体类
public class User{
private String name;
private String password;
private int age;
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void setPassword(String password){
this.password = password;
}
public String getPassword(){
return this.password;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return this.age;
}
}
// 设置action
XXXAction {
private User user;// 声明成员变量,提供get,set方法
public void setUser(User user){
this.user = user;
}
public User getUser(){
return this.user;
}
}
// jsp页面,传值
<input name="user.name"/>
<input name="user.password"/>
<input name="user.age"/>
// 取值
<s:property value="ognl表达式"/>
// 对当前就是
<s:property value="#user.name"/>取到user对象中name的值,
因为前面的文字标红之后,就变形了,所以,在这里在手打一次
// 取值
<s:property value="ognl表达式"/>
// 对当前就是
<s:property value="#user.name"/>
<s:property value="#user.password"/>
<s:property value="#user.age"/>
前面取值说到ognl表达式了,有些可能不理解,我就这么说,值栈用的就是ognl表达式,大家可以去试试,把ognl的jar扔掉,看页面报错不,
另外我附上一份ognl表达式的笔记,是我以前整理的,里面存值还是用的ValueStack,主要给大家看的是ognl表达式的语法,存值,取值前面已经说了,用成员变量替换了,好,废话少说,上代码:
a) OGNL表达式
概念:OGNL表达式是一个获取数据的技术
注意:独立的技术组件,不属于Struts2框架
b) ValueStack值栈
作用:管理(存储),一次请求涉及到的数据
一次请求涉及到的数据:
1.client请求提交的数据
2.作用域中的数据
request
session
application
parameters
好处:与视图层(view)解耦和
获得ViewStack:
ActionContext ctx = ActionContext.getContext();
ValueStack vs = ctx.getValueStack();
ValueStack的生命周期:一次请求有效
c) Struts2的标签
// OGNL表达式
/**
* 目的:是获得root区存储对象属性的值
* 语法:获得root区存储对象的属性值,直接通过属性名获取
*
* @throws OgnlException
*/
@Test
public void test1() throws OgnlException {
User user = new User(1, "张三", "123");
System.out.println(Ognl.getValue("id", user));
System.out.println(Ognl.getValue("name", user));
System.out.println(Ognl.getValue("pssword", user));
}
/******************************************************/
/******************************************************/
/**
* 目的:获取root区存储的对象的对象属性的内容【User[address]】
* 语法:address.属性名
*
* @throws OgnlException
*/
@Test
public void test2() throws OgnlException {
User user = new User();
Address address = new Address("bj", "shangdi");
user.setAddress(address);
System.out.println(Ognl.getValue("address.city", user));
System.out.println(Ognl.getValue("address.street", user));
}
/******************************************************/
/******************************************************/
/**
* 目的:获取root区存储的list,set,数组的内容
* 语法:属性名[index],eg,有属性list,则取值list[index]
* @throws OgnlException
*/
@Test
public void test3() throws OgnlException {
User user = new User();
List<String> list = new ArrayList<String>();
list.add("123");
list.add("456");
user.setList(list);
System.out.println(Ognl.getValue("list[0]", user));
System.out.println(Ognl.getValue("list[1]", user));
}
/******************************************************/
/******************************************************/
/**
* 目的:获取root区存储的map的值
* 语法:属性名['key']如果key是integer类型,则可以省略单引号
* @throws OgnlException
*/
@Test
public void test4() throws OgnlException {
User user = new User();
Map<String, String> map = new HashMap<String, String>();
map.put("suns", "111");
map.put("huxz", "222");
user.setMap(map);
System.out.println(Ognl.getValue("map['suns']", user));
System.out.println(Ognl.getValue("map['huxz']", user));
}
/******************************************************/
/******************************************************/
/**
* OGNL表达式可以进行算数运算,逻辑运算,以及调用属性对应的方法
* @throws OgnlException
*/
@Test
public void test5() throws OgnlException {
User user = new User(1, "suns", "123456");
//算数运算
System.out.println(Ognl.getValue("id * 100", user));
// 逻辑运算
System.out.println(Ognl.getValue("id > 100", user));
System.out.println(Ognl.getValue("name == 'suns'", user));
// 调用数据类型的方法
System.out.println(Ognl.getValue("name.length()", user));
System.out.println(Ognl.getValue("name.toUpperCase()", user));
System.out.println(Ognl.getValue("name.equals('suns')", user));
}
/******************************************************/
/******************************************************/
/**
* 目的:获取contextMap区的值
* @throws OgnlException
*/
@Test
public void test6() throws OgnlException {
User user = new User(1, "suns", "123456");
User user2 = new User(2, "huxz", "123555");
Map<String, User> contextMap = new HashMap<String, User>();
contextMap.put("suns", user);
contextMap.put("huxz", user2);
System.out.println(Ognl.getValue("#suns.name", contextMap, ""));
System.out.println(Ognl.getValue("#huxz.id", contextMap,""));
}
/******************************************************/
/******************************************************/
// 客户端接收服务器数据
// 接收单个数据
<%
ActionContext cxt = ActionContext.getContext();
ValueStack vs = cxt.getValueStack();
vs.setValue("#request.name", "suns");
User user = new User(1,"suns","123456");
vs.setValue("#session.user", user);
%>
<h1>
<s:property value="#request.name"/>
</h1>
<h1>
<s:property value="#session.user.name.toUpperCase() == 'suns'"/>
</h1>
/******************************************************/
/******************************************************/
//if条件判断
<%
ActionContext cxt = ActionContext.getContext();
ValueStack vs = cxt.getValueStack();
vs.setValue("#request.name", "suns");
%>
<s:if test="#request.name == 'suns'">
<h1>success</h1>
</s:if>
<s:else>
<h1>fail</h1>
</s:else>
/******************************************************/
/******************************************************/
// list,set,数组遍历
<%
ActionContext cxt = ActionContext.getContext();
ValueStack vs = cxt.getValueStack();
User user1 = new User(1,"suns1","123123");
User user2 = new User(2,"suns2","212212");
User user3 = new User(3,"suns3","323323");
//User[] users = new User[]{user1,user2,user3};
/*
List<User> users = new ArrayList<User>();
users.add(user1);
users.add(user2);
users.add(user3);
*/
Set<User> users = new HashSet<User>();
users.add(user1);
users.add(user2);
users.add(user3);
vs.setValue("#request.users", users);
%>
<s:iterator value="#request.users">
<h1>
<s:property value="id"/>
<s:property value="name"/>
<s:property value="password"/>
</h1>
</s:iterator>
/******************************************************/
/******************************************************/
// map遍历
<%
ActionContext cxt = ActionContext.getContext();
ValueStack vs = cxt.getValueStack();
Map<Integer,User> map = new HashMap<Integer,User>();
map.put(1, new User(1,"suns1","111"));
map.put(2, new User(2,"suns2","222"));
map.put(3, new User(3,"suns3","333"));
vs.setValue("#request.map", map);
%>
<s:iterator value="#request.map">
<h1><s:property value="key"/> == <s:property value="value"/></h1>
</s:iterator>
/******************************************************/
/******************************************************/
// 状态遍历
<s:iterator value="" status="sta">
#sta.count 当前遍历次数
#sta.index 获得当前遍历的下标
#sta.even 当前是否是偶次遍历 boolean
#sta.odd 当前是否是奇次遍历 boolean
</s:iterator>
<%
ActionContext cxt = ActionContext.getContext();
ValueStack vs = cxt.getValueStack();
User user1 = new User(1,"suns1","123123");
User user2 = new User(2,"suns2","212212");
User user3 = new User(3,"suns3","323323");
User[] users = new User[]{user1,user2,user3};
vs.setValue("#request.users", users);
%>
<s:iterator value="#request.users" status="sta">
<h1>
<s:property value="name"/>
<s:property value="#sta.count"/>
<s:property value="#sta.index"/>
<s:property value="#sta.even"/>
<s:property value="#sta.odd"/>
</h1>
</s:iterator>