接着上一篇,这篇学习如何在action和jsp页面中传值.并配合modelDriven传值学习
1.首先我们要在action中设置私有属性,并实现其get和set方法
public class UserAction{
private String username;
private String password;
private int age;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
2.在里面增加一个list方法,此方法会跳转到list.jsp页面,并且这个方法中调用set方法就可以传值了
public String list(){
this.setUsername("小明");
this.setPassword("1234");
this.setAge(15);
return "list";
}
3.jsp页面获取,可以用EL表达式,也可以用struts的标签
${username}-----${password}----${age}
<s:property value="username"/>
<s:property value="password"/>
<s:property value="age"/>
使用这种方式的话,不需要get和set方法,可以在Action中按如下设置参数
public String list(){
ActionContext.getContext().put("username","小明");
ActionContext.getContext().put("password","1234");
ActionContext.getContext().put("age",12);
return "list";
}
然后jsp页面获取
这里注意下,如果使用ActionContext,那么用s:property获取参数的时候,非String类型的需要加#号,不然会报错,类型无法转换过去,开发中为了统一,只要是ActionContext传的参数都会加#号
${username}-----${password}----${age}
<s:property value="#username"/>
<s:property value="#password"/>
<s:property value="#age"/>
传统方式就是request来传值,我们可以通过ServletActionContext来获取这些类的实例
public String list(){
ServletActionContext.getRequest().setAttribute("username","小明");
ServletActionContext.getRequest().setAttribute("password","12345");
ServletActionContext.getRequest().setAttribute("age",13);
return "list";
}
然后jsp访问需要按照以下规则
${username}-----${password}----${age}
<s:property value="#request.username"/>
<s:property value="#request.password"/>
<s:property value="#request.age"/>
struts2采用的ognl这种表达式语言通过简单一致的语法,可以任意存取对象的属性或者调用对象的方法,能够遍历整个对象的结构图,实现对象属性类型的转换等功能。
下面来测试ognl
大体上分两种,一种是在root根节点下面寻找,一种是在map集合中寻找
@Test
public void test01() {
try {
User u = new User(1,"tangsheng","唐僧");
Department dep = new Department("财务处");
u.setDep(dep);
//第二个参数是root,从根部寻找是不需要加#号的
System.out.println(Ognl.getValue("nickname",u));
//对于对象中的其他对象用这种方式索引
System.out.println(Ognl.getValue("dep.name",u));
} catch (OgnlException e) {
e.printStackTrace();
}
}
@Test
public void test02() {
try {
Map<String,Object> ctx = new HashMap<String,Object>();
User u = new User(1,"tangsheng","唐僧");
Department dep = new Department("财务处");
u.setDep(dep);
Role r = new Role(1,"超级管理员");
ctx.put("user",u);
ctx.put("role", r);
//以下表达式是在root中找,u是root
System.out.println(Ognl.getValue("username",ctx,u));
//#user.username是在ctx这个map中找
System.out.println(Ognl.getValue("#user.username",ctx,u));
System.out.println(Ognl.getValue("#role.name",ctx,u));
//目前root是ctx所以可以直接取得到
System.out.println(Ognl.getValue("role.name",ctx,ctx));
//Ognl其实就是一个大的Context,根的key就是root,所以可以通过#root.xx来取值
System.out.println(Ognl.getValue("#root.username",ctx,u));
} catch (OgnlException e) {
e.printStackTrace();
}
}
@Test
public void test03() {
try {
List<User> users = new ArrayList<User>();
users.add(new User(1,"ts","唐僧"));
users.add(new User(2,"ss","沙僧"));
users.add(new User(3,"bj","八戒"));
users.add(new User(4,"wk","悟空"));
//如果要取list中的元素,需要通过#root[index]来完成取值
System.out.println(Ognl.getValue("#root[1].nickname", users));
} catch (OgnlException e) {
e.printStackTrace();
}
}
@Test
public void test04() {
try {
List<User> users = new ArrayList<User>();
users.add(new User(1,"ts","唐僧"));
users.add(new User(2,"ss","沙僧"));
users.add(new User(3,"bj","八戒"));
users.add(new User(4,"wk","悟空"));
//如果要取list中的元素,需要通过#root[index]来完成取值
System.out.println(Ognl.getValue("#root[1].nickname", users));
//Ognl还可以完成方法的调用
System.out.println(Ognl.getValue("#root[0].sum(1,3)", users));
User u = new User();
System.out.println(Ognl.getValue("hello('world')", u));
//可以通过调用list中的get()方法获取某个下标的对象,然后完成导航
System.out.println(Ognl.getValue("get(0).username", users));
} catch (OgnlException e) {
e.printStackTrace();
}
}
ValuteStack栈中有两个内容来存储值,一个是CompoundRoot,这个是栈结构,也就是先进后出.而ActionContext是一个map集合,存入键值对,还有request,session等这些值.
对于root根节点,是CompoundRoot这个栈的栈顶元素,对于其他元素则需要使用#root[index]来访问.
对于ActionContext的基本值可以直接#号访问,但对于request这样的对象,则需要#request.name这样的方式来访问.
另外直接的set和get传值方法也是利用CompoundRoot这个栈来存储的,具体的都可以利用debug标签来测试
//可以通过这种方式来操纵栈
ActionContext.getContext().getValueStack().push(user);
效果图如下:
所谓ModelDriven,意思是直接把实体类当成页面数据的收集对象。比如,有实体类User如下:
public class User {
private String username;
private String password;
private int age;
private String nickname;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
@Override
public String toString() {
return username+"--"+password+"---"+age;
}
}