struts2学习笔记3
黑马视频的学习笔记3:
ognl概述
ognl是一种表达式,它的功能比el表达式更加强大, 主要学习通过它和struts2的标签一起使用,来操作值栈里的数据。
ognl不是struts2的一部分,是一个单独的项目,只是经常和struts2一起使用
ognl入门
首先在jsp页面中引入struts2的标签库。使用标签和ognl表达式
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!--引入struts2的标签库 -->
<%@ taglib uri="/struts-tags" prefix="s" %>
<!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>Insert title here</title>
</head>
<body>
<s:property value="'haha'.length()"/>
</body>
</html>
什么是值栈
1.在jsp里面,在servlet里面操作,把数据放到域对象里面,在页面中使用el表达式获取数据。
2.值栈:struts2本身提供的一种存储机制,类似于域对象,可以存值和取值。在action里把数据放到值栈里面,在页面中取数据
注意:servlet在第一次访问时创建,只创建一次,是单实例的。而action每次访问时都会创建,是多实例的。
3.值栈的存储位置
每次访问action,会创建一个action对象,在每一个action对象里面,有且只有一个值栈对象
获取值栈对象
package cn.itcast.action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
public class UserAction extends ActionSupport{
@Override
public String execute() throws Exception {
//获取actioncontext对象
ActionContext context=ActionContext.getContext();
//使用actioncontext对象的方法得到值栈对象
ValueStack stack1=context.getValueStack();
return NONE;
}
}
值栈内部结构
栈的结构图:
值栈结构图:
debug标签:
action的代码
package cn.itcast.action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
public class UserAction extends ActionSupport{
@Override
public String execute() throws Exception {
//获取actioncontext对象
ActionContext context=ActionContext.getContext();
//使用actioncontext对象的方法得到值栈对象
ValueStack stack1=context.getValueStack();
return NONE;
}
}
配置文件:
ruts>
<package name="demo1" extends="struts-default" namespace="/">
<action name="valuestackdemo1" class="cn.itcast.action.ValueStackDemoAction">
<result name="success">/valuestack.jsp</result>
</action>
<action name="valuestackdemo2" class="cn.itcast.action.ValueStackDemoAction2">
<result name="success">/valuestack.jsp</result>
</action>
<action name="valuestack" class="cn.itcast.valuestack.ValueStackAction">
<result name="success">/valuestack.jsp</result>
</action>
</package>
jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!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>Insert title here</title>
</head>
<body>
<s:debug></s:debug>
值栈的内部结构:
向值栈中放数据
1.放数据有多种方式,最常用的是在action里面定义变量,生成变量的get方法
action的代码:
package cn.itcast.action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
public class ValueStackDemoAction extends ActionSupport {
private String name;
public String getName() {
return name;
}
@Override
public String execute() throws Exception {
ActionContext context=ActionContext.getContext();
ValueStack stack1=context.getValueStack();
// 用值栈的set方法放数据到值栈里面
stack1.set("username", "it.castheima");
// 用值栈的push方法也可以放数据到值栈里面
stack1.push("abcd");
//在具体执行的方法中设置name值
name="abcdefg";
return SUCCESS;
}
}
放到值栈里面
2.向值栈中放对象
先创建实体类user
package cn.itcast.entity;
public class User {
private String username;
private String password;
private String address;
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 String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
配置文件
<action name="valuestackdemo2" class="cn.itcast.action.ValueStackDemoAction3">
<result name="success">/valuestack.jsp</result>
</action>
action的代码
package cn.itcast.action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
import cn.itcast.entity.User;
public class ValueStackDemoAction3 extends ActionSupport {
private User user=new User();
public User getUser() {
return user;
}
@Override
public String execute() throws Exception {
user.setUsername("lucy");
user.setPassword("123");
user.setAddress("美国");
return SUCCESS;
}
}
3.向值栈中放入list集合
配置文件
<action name="valuestackdemo2" class="cn.itcast.action.ValueStackDemoAction2">
<result name="success">/valuestack.jsp</result>
</action>
action的代码
package cn.itcast.action;
import java.util.ArrayList;
import java.util.List;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
import cn.itcast.entity.User;
public class ValueStackDemoAction2 extends ActionSupport {
private List<User> list=new ArrayList<User>();
public List<User> getList() {
return list;
}
@Override
public String execute() throws Exception {
User user1=new User();
user1.setUsername("zhangsan");
user1.setPassword("666");
user1.setAddress("tiantang");
User user2=new User();
user2.setUsername("lisi");
user2.setPassword("888");
user2.setAddress("diyu");
list.add(user1);
list.add(user2);
return SUCCESS;
}
}
从值栈中取数据
使用struts2标签和ognl表达式
先向值栈中放入数据
package cn.itcast.valuestack;
import java.util.ArrayList;
import java.util.List;
import com.opensymphony.xwork2.ActionSupport;
import cn.itcast.entity.User;
public class ValueStackAction extends ActionSupport {
private String username;
private User user=new User();
private List<User> list=new ArrayList<User>();
public String getUsername() {
return username;
}
public User getUser() {
return user;
}
public List<User> getList() {
return list;
}
@Override
public String execute() throws Exception {
username="itcast";
user.setUsername("wiles");
user.setPassword("666");
user.setAddress("伦敦");
User user1=new User();
user1.setUsername("zhangsan");
user1.setPassword("666");
user1.setAddress("tiantang");
User user2=new User();
user2.setUsername("lisi");
user2.setPassword("888");
user2.setAddress("diyu");
list.add(user1);
list.add(user2);
return SUCCESS;
}
}
1.获取字符串
2.获取对象
3.获取list集合
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!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>Insert title here</title>
</head>
<body>
<s:debug></s:debug>
<!--从值栈中获取字符串,少用 -->
<s:property value="username" />
<br />
<!-- 从值栈中获取对象 -->
<s:property value="user.username" /><br/>
<s:property value="user.password" /><br/>
<s:property value="user.address" /><br/>
<br/>
获取list集合里面的值:<br/>
<!--从值栈中获取list对象的值第一种方式 -->
<s:property value="list[0].username" /><br/>
<s:property value="list[0].password" /><br/>
<s:property value="list[0]. address" /><br/>
第二种方式:<br/>
<!--第二种方式 -->
<s:iterator value="list">
<s:property value="username"/><br/><br/>
<s:property value="password"/><br/><br/>
<s:property value="address"/><br/><br/>
</s:iterator>
第三种方式:<br/>
<!--第三种方式 ,由于struts2的优化机制,把数据放到值栈的contex里面,从context里面 的数据,要使用# -->
<s:iterator value="list" var="user">
用户名: <s:property value="#user.username"/><br/><br/>
密码:<s:property value="#user.password"/><br/><br/>
地址: <s:property value="#user.address"/><br/><br/>
</s:iterator>
<br/>
<br/>
第四种方式,使用foreach标签+el表达式:<br/>
<c:forEach items="${list}" var="user">
${user.username}<br/>
${user.password}<br/>
${user.address}<br/>
</c:forEach>
<!--获取set方法放到值栈中的值 -->
<s:property value="username"/>
<br/><br/>
<!--获取push方法放到值栈中的值 -->
<s:property value="[0].top"/>
<!-- 相当于表单标签的input标签 -->
<s:textfield name="username" value="%{#request.req}">
</s:textfield>>
</body>
</html>
el表达式能获取值栈数据(为什么)
el表达式可以获取域对象的数据,(域对象里面放值用setAttribute,取值用getAttribute)。底层增强了request对象里面的getAttribute方法:先从域对象里面取值,取到就返回,如果取不到就到值栈中把值取出来,放到域对象里面
ognl的#和%的使用
1、 #号获取context里面的数据
public String execute() throws Exception {
HttpServletRequest request=ServletActionContext.getRequest();
request.setAttribute("req", "reqvalue"); }
jsp页面取值:
<s:property value="#request.req"/>
2、struts2的表单标签中%加上ognl表达式一起使用才能被识别
jsp页面:
<!-- 相当于表单标签的input标签 -->
<s:textfield name="username" value="%{#request.req}">
</s:textfield>>