一、值栈对象的数据入库
>>>>>> 往List集合中添加数据
public String updateView() {
//获取员工
EmpEntity emp2 = empService.findById(emp.getEmpId());
ActionContext ac = ActionContext.getContext();
ValueStack vs = ac.getValueStack();
vs.push(emp2);
return "updateView";
}
>>>>>> 往Map集合中添加数据
public String updateView() {
//获取员工
EmpEntity emp2 = empService.findById(emp.getEmpId());
//将数据放到Map集合中
//request
HttpServletRequest req = ServletActionContext.getRequest();
req.setAttribute("emp", emp2);
//session
HttpSession session = req.getSession();
session.setAttribute("emp", emp2);
//application
PageContext pageContext = ServletActionContext.getPageContext();
pageContext.setAttribute("emp", emp2);
//自定义
ActionContext ac = ActionContext.getContext();
ac.put("emp2", emp2);
return "updateView";
}
二、Struts2 调试标签
<!-- 打印值栈数据 -->
<s:debug></s:debug>
三、Struts2 常规标签
3.1 s:property 属性标签
<s:property value=“#name" default="a default value" />
default:可选属性,如果需要输出的属性值为null,则显示该属性指定的值
escape:可选属性,指定是否格式化HTML代码。
value: 可选属性,指定需要输出的属性值,如果没有指定该属性,
则默认输出ValueStack栈顶的值。
3.1.1 从值栈对象中List集合取值
1.从值栈对象中的list集合取值
<s:property value="user"/>
3.1.2 从值栈对象中Map集合取值
2.从值栈对象中的map集合取值
<s:property value="#request.msg"/>
获取request域对象中的数据
<s:property value="#session.msg"/>
获取session域对象中的数据
3.1.3 简单运算
s:propertity标签做简单运算
<s:property value="1==1?11:22"/>
<s:property value="1+2"/>
<s:property value="#st.count==1?11:22"/>
3.1.4 案例:常规标签取值
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<!-- 页面: 必须要拿到ValueStack -->
<br/>1. 取根元素的值<br/>
<s:property value="user.id"/>
<s:property value="user.name"/>
<s:property value="user.address"/>
<s:property value="user.address.city"/>
<s:property value="user.address.province"/>
<br/>2. 取非根元素的值<br/>
<s:property value="#request.cn"/>
<s:property value="#session.Session_data"/>
<s:property value="#application.Application_data"/> <br/>
<!-- 自动找request/session/application,找到后立刻返回 -->
<s:property value="#request_data"/>
<s:property value="#attr.Session_data"/>
<s:property value="#attr.Application_data"/> <br/>
<!-- 获取请求的参数数据 -->
<s:property value="#parameters.userName"/>
<!-- struts的调试标签:可以观测值栈数据 -->
<s:debug></s:debug>
</body>
</html>
3.2 s:iterator 迭代标签
Iterator:标签用于对集合进行迭代(List,Map,数组)。
value:可选属性,指定被迭代的集合。
如果没有设置该属性,则使用ValueStack栈顶的集合。
var: 可选属性,引用变量的名称.
status:可选属性,该属性指定迭代时的IteratorStatus实例。
该实例包含如下几个方法:
int getCount(),返回当前迭代了几个元素。
int getIndex(),返回当前迭代元素的索引。
boolean isEven(),返回当前被迭代元素的索引是否是偶数
boolean isOdd(),返回当前被迭代元素的索引是否是奇数
boolean isFirst(),返回当前被迭代元素是否是第一个元素。
boolean isLast(),返回当前被迭代元素是否是最后一个元素。
3.2.1 status属性
案例1:
<s:iterator value="allList" status="st">
st.getCount():<s:property value="#st.count"/>
st.getIndex():<s:property value="#st.index"/>
st.isEven():<s:property value="#st.even"/>
st.isOdd():<s:property value="#st.odd"/>
st.isFirst:<s:property value="#st.first"/>
st.isLast():<s:property value="#st.last"/><br>
</s:iterator>
案例2:
<table border="1">
<s:iterator value="allList" var="person" status="st">
<tr class=<s:property value="#st.even?'even':'odd'"/> >
<td><s:property value="#person.name"/></td>
</tr>
</s:iterator>
</table>
3.2.2 使用标签遍历List集合和Map集合
>>>>>> UserAction.java
public class UserAction extends ActionSupport{
/**
* 1.通过值栈对象操作list集合
* @return
*/
public String demo() {
List<UserEntity> list=new ArrayList<UserEntity>();
Map<String,UserEntity> map=new HashMap<String, UserEntity>();
for(int i=0;i<10;i++) {
UserEntity u=new UserEntity();
u.setName("xxx"+i);
u.setAge(i);
list.add(u);
map.put(i+"", u);
}
ActionContext.getContext().put("list", list);
ActionContext.getContext().put("map", map);
return "index";
}
}
>>>>>>> struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="xxxx" extends="struts-default">
<global-results>
<result name="input">/register.jsp</result>
</global-results>
<action name="demo" class="org.jsft.demo.UserAction" method="demo">
<result name="index">/index.jsp</result>
</action>
</package>
</struts>
>>>>>> inedx.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<style type="text/css">
.y{
background-color: red;
}
.n{
background-color: yellow;
}
</style>
<body>
<s:debug></s:debug>
<s:property/>
<h1>遍历list集合</h1>
<table border="1" colspacing="1">
<s:iterator value="#list" var="user" status="vs">
<tr class=<s:property value="#vs.even?'y':'n'"/>>
<td><s:property value="#vs.count"/></td>
<td><s:property value="#user.name"/></td>
<td><s:property value="#user.age"/></td>
</tr>
</s:iterator>
</table>
<s:property value="1+2"/>
<h1>遍历map集合</h1>
<table border="1">
<s:iterator value="#map" var="en" status="vs">
<tr class=<s:property value="#vs.even?'y':'n'"/>>
<td><s:property value="#en.key"/></td>
<td><s:property value="#en.value"/></td>
<td><s:property value="#en.value.name"/></td>
<td><s:property value="#en.value.age"/></td>
</tr>
</s:iterator>
</table>
<s:iterator>
</s:iterator>
</body>
</html>
>>>>>> 测试:
访问 http://localhost:8080/struts4/demo
3.2.3 使用迭代标签构建集合
<!-- 构建list集合 -->
<s:iterator value="{'1','2','3'}" var="str">
<s:property value="#str"/>
</s:iterator>
<!-- 构建map集合 -->
<s:iterator value="#{'cn':'CN','eg':'EG' }" var="en">
<s:property value="#en.key"/>
<s:property value="#en.value"/>
</s:iterator>
3.3 s:if 标签
<s:if test="#age==23">
23
</s:if>
<s:elseif test="#age==21">
21
</s:elseif>
<s:else>
都不等
</s:else>
If’标签可单独使用也可以和‘Else If’标签和(或)一个多个‘Else’一起使用
3.3.1 s:if 标签从session中取值
>>>>>> 后端往值栈对象中添加数据
//存入session
ActionContext.getContext().getSession().put("userInfo", admin2);
>>>>>> 前端取值
<s:if test="#session.userInfo != null">
<div style="display:inline-block;margin:0px auto;">
欢迎你,${userInfo.account}
<a href="./adminAction_loginOut">退出</a>
<a href="./empAction_addView">新增</a>
</div>
</s:if>
<s:else>
<div style="display:inline-block;margin:0px auto;">
没有登录!!!
<s:a href="./login.jsp">登录</s:a>
<s:a href="./register">注册</s:a>
</div>
</s:else>
四、Struts2 非常规标签
4.1 s:a 标签
从值栈对象中的List集合取值:
<s:a href="./index?name=%{name}" > 百度 </s:a>
从值栈对象中的Map集合取值:
<s:a href="./index?name=%{#name}" > 百度 </s:a>
<s:a href="./index?name=%{#request.name}" > 百度 </s:a>
4.2 表单标签
4.2.1 s:textfield 标签
<s:textfield id="" name="" value="" label=""></s:textfield>
4.2.1.1 案例:从值栈对象中List集合取值
<s:textfield value="%{name}" ></s:textfield>
从值栈对象中取值,自上而下,取到为止。
>>>>>> EmpEntity.java
public class EmpEntity {
private String empId;
private String name;
private int age;
private DeptEntity dept;
>>>>>> EmpAction.java【将数据放入栈顶】
public class EmpAction extends ActionSupport implements ModelDriven<EmpEntity> {
private IEmpService empService;
/**
* 跳转到新增员工界面
* @return
*/
public String updateView() {
//获取员工
EmpEntity emp2 = empService.findById(emp.getEmpId());
//将数据放到值栈对象的栈顶
ActionContext ac = ActionContext.getContext();
ValueStack vs = ac.getValueStack();
vs.push(emp2);
return "updateView";
}
}
>>>>>> index.jsp【从值栈对象中取值,自上而下取值】
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>修改</title>
</head>
<body>
<s:textfield value="%{name}" ></s:textfield>
<s:textfield value="%{age}" ></s:textfield>
</body>
</html>
4.2.1.2 案例:从值栈对象中Map集合取值
>>>>>> EmpEntity.java
public class EmpEntity {
private String empId;
private String name;
private int age;
private DeptEntity dept;
>>>>>> EmpAction.java【将数据放入Map中】
public class EmpAction extends ActionSupport implements ModelDriven<EmpEntity> {
private IEmpService empService;
/**
* 跳转到新增员工界面
* @return
*/
public String updateView() {
//获取员工
EmpEntity emp2 = empService.findById(emp.getEmpId());
//将数据放到Map集合中【方式一】
HttpServletRequest req = ServletActionContext.getRequest();
req.setAttribute("emp", emp2);
//将数据放到Map集合中【方式二】
ActionContext ac = ActionContext.getContext();
ac.put("emp2", emp2);
return "updateView";
}
}
>>>>>> index.jsp【从值栈对象中取值,自上而下取值】
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>修改</title>
</head>
<body>
<s:textfield value="%{#request.emp.name}" ></s:textfield>
<s:textfield value="%{#request.emp.age}" ></s:textfield>
<s:textfield value="%{#emp2.name}" ></s:textfield>
<s:textfield value="%{#emp2.age}" ></s:textfield>
</body>
</html>
通过标签的name属性取值(只能获取值栈对象中的list栈中数据):
<s:textfield name="name" ></s:textfield><br/>
自动获取值栈对象中list栈中对象的name数据。
通过标签的value属性取值(可以获取整个值栈对象中的数据):
<s:textfield value="%{pwd}" ></s:textfield><br/>
Struts2表单的表单项标签有很多。但是只有这一个标签可以从值栈对象中取值。
并且,Struts2还把这种技术称之为数据回显。
自身感觉很垃圾。 只是拿来学习用,实战中还是算了。
4.2.1.3 案例:获取值栈对象中的Map集合数据
>>>>>> UserAction.java
public class UserAction extends ActionSupport{
public String demo() {
ActionContext ac = ActionContext.getContext();
UserEntity user=new UserEntity();
user.setAge(12);
user.setName("小白");
user.setPwd("121");
ac.put("u", user);
return "index";
}
}
>>>>>> struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="xxxx" extends="struts-default">
<global-results>
<result name="input">/register.jsp</result>
</global-results>
<action name="demo" class="org.jsft.demo.UserAction" method="demo">
<result name="index">/index.jsp</result>
</action>
</package>
</struts>
>>>>>> index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<s:debug></s:debug>
<!-- 表单 -->
<s:form action="./demo" method="post" theme="simple">
用户名:<s:textfield value="%{#u.name}" ></s:textfield><br/>
密码:<s:textfield value="%{#u.pwd}" ></s:textfield><br/>
<s:submit value="提交"></s:submit>
</s:form>
</body>
</html>
>>>>>> 测试:
======》访问 http://localhost:8080/struts4/demo
4.2.2 表单标签
<s:form action="./demo" method="post" >
<s:textfield name="user.name" label="用户名"></s:textfield>
<s:password name="user.pwd" label="密码"></s:password>
<s:submit value="提交"></s:submit>
</s:form>
4.2.2.1 表单标签设置主题
1.使用struts2表单标签自带的主题
<!-- 表单 -->
<s:form action="./demo" method="post" >
<s:textfield name="user.name" label="用户名"></s:textfield>
<s:password name="user.pwd" label="密码"></s:password>
<s:submit value="提交"></s:submit>
</s:form>
2.取消struts2表单标签自带的主题,用户可以自定义
<!-- 表单 -->
<s:form action="./user_register" method="post" theme="simple" >
用户名:<s:textfield name="user.name"></s:textfield>
<s:fielderror fieldName="user.name"></s:fielderror>
<br/>
密码:<s:textfield name="user.pwd"></s:textfield>
<s:fielderror fieldName="user.pwd"></s:fielderror>
<br/>
生日:<s:textfield name="user.birth"></s:textfield>
<s:fielderror fieldName="user.birth"></s:fielderror>
<br/>
<s:submit value="提交"></s:submit>
</s:form>
struts表单标签自带样式,所以对于开发者来说很难控制。
所以struts提供了表单标签的主题设置,只需设置简单模式,就可以取消表单标签自带的样式。
取消表单标签自带样式有两种方式:
方式一:表单标签添加theme属性。
<s:form action="./user_register" method="post" theme="simple" >
方式二:
对于struts标签默认的主题样式:
default.xml/struts.ui.theme=xhtml
可以通过常量修改, 改为简单主题:
<!-- 修改主题 (当前项目所有的标签都用此主题)-->
<constant name="struts.ui.theme" value="simple"></constant>
4.2.2.2 表单提交案例
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 表单 -->
<s:form action="./user_register" method="post">
用户名:<s:textfield name="user.name"></s:textfield>
<s:fielderror fieldName="user.name"></s:fielderror>
<br/>
密码:<s:textfield name="user.pwd"></s:textfield>
<s:fielderror fieldName="user.pwd"></s:fielderror>
<br/>
生日:<s:textfield name="user.birth"></s:textfield>
<s:fielderror fieldName="user.birth"></s:fielderror>
<br/>
<s:submit value="提交"></s:submit>
</s:form>
</body>
</html>
4.2.3 其他表单标签
>>>>>> 密码标签
<s:password name="user.pwd" label="密码"></s:password>
>>>>>> 下拉框标签
<!-- 下拉框 -->
<!--
Struts下拉列表标签:
name="deptId" 下拉列表标签的名称(服务器根据这个名称获取选择的项的实际的值value值)
headerKey 默认选择项的实际的值 //不需要,可以不写
headerValue 默认下拉列表显示的内容 //不需要,可以不写
list 下拉列表显示数据的集合
listKey 集合对象的哪个属性作为下拉列表的实例的值,即value值
listValue 集合对象的哪个属性作为下拉列表显示的值
value 默认选择的项的设置
-->
<s:select
name="deptId"
headerKey="-1"
headerValue="请选择"
list="%{#depts}"
listKey="id"
listValue="name"
value="-1"
></s:select>
>>>>>> 隐藏域标签
<s:hidden name="empId" value="%{empId}" ></s:hidden>
五、Struts2标签取值 - Ognl表达式
5.1 Ognl表达式来源
在JSP页面中,从前端获取后台数据可以使用EL表达式,获取域对象中的数据。
在struts中,由于struts引入了值栈对象,所以struts标签引入了另一套取值体系,即ognl表达式。
5.2 Ognl表达式
1. 直接获取值栈对象中List集合数据
2. # 获取值栈对象中Map集合数据(非根元素值)
3. % 提供一个ognl表达式运行环境
<body>
<br/>获取request域数据<br/>
<!-- property 标签是对象类型的标签,默认支持ognl表达式, 会从根元素去China名称对应的值 -->
<s:property value="China"/> <br/>
<!-- 如果直接赋值,需要用单引号 -->
<s:property value="'China'"/> <br/>
<s:property value="%{#request.cn}"/> <br/>
<!-- 值类型的标签,value值默认就是值类型,不支持ognl表达式 -->
国家:<s:textfield name="txtCountry" value="%{#request.cn}"></s:textfield>
</body>
5.3 Struts2标签从值栈对象中取值
5.3.1 常规标签从值栈对象中取值(类似于EL表达式)
从值栈对象中的List集合取值:(自上而下,取到为止。栈顶)
属性标签:
<s:property value=“name" default="a default value" />
迭代标签:
<s:iterator value="allList" status="st">
st.getCount():<s:property value="#st.count"/>
</s:iterator>
if标签:
<s:if test="age==23">
23
</s:if>
从值栈对象中的Map集合取值:
属性标签:
<s:property value="#name"/>
<s:property value="#request.msg"/> 从request域对象中取值
迭代标签:
<s:iterator value="#requets.allList" status="st">
st.getCount():<s:property value="#st.count"/>
</s:iterator>
if标签:
<s:if test="#age==23">
23
</s:if>
5.3.2 非常规标签从值栈对象中取值(类似于EL表达式)
从值栈对象中的List集合取值:(自上而下,取到为止。栈顶)
value="%{name}"
从值栈对象中的Map集合取值:
value="%{#request.name}"
>>>>>> 案例
从值栈对象中的List集合取值:(自上而下,取到为止。栈顶)
<s:a href="./index?name=%{name}" > 百度 </s:a>
<s:textfield value="%{name}" ></s:textfield>
从值栈对象中的Map集合取值:
<s:a href="./index?name=%{#name}" > 百度 </s:a>
<s:textfield value="%{#name}" ></s:textfield>
<s:textfield value="%{#request.name}" ></s:textfield>
六、struts标签取值与数据回显
Struts标签赋予了两种功能:
1、Struts2标签可以从值栈对象中手动获取数据,类似于jsp中的EL表达式。
2、Struts2标签还可以使用数据回显功能从值栈对象中自动获取数据。
Struts2标签手动从值栈对象中获取,需要通过value属性获取。
Struts2标签数据回显自动从值栈对象中获取,需要通过name属性获取。
6.1 Struts2标签手动从值栈对象中获取数据
===>> 通过标签的value属性取值
UserAction.java
public class UserAction extends ActionSupport{
/**
* 1.通过值栈对象操作list集合
* @return
*/
public String demo() {
//key:xxx,value:vvv。放入值栈对象中的map集合中
ActionContext ac = ActionContext.getContext();
ValueStack vs = ac.getValueStack();
UserEntity user=new UserEntity();
user.setAge(12);
user.setName("小白");
user.setPwd("121");
vs.push(user);
return "index";
}
}
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="xxxx" extends="struts-default">
<global-results>
<result name="input">/register.jsp</result>
</global-results>
<action name="demo" class="org.jsft.demo.UserAction" method="demo">
<result name="index">/index.jsp</result>
</action>
</package>
</struts>
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<s:debug></s:debug>
<!-- 表单 -->
<s:form action="./demo" method="post" theme="simple">
用户名:<s:textfield name="" value="#name"></s:textfield><br/>
密码:<s:textfield name="" value="#pwd"></s:textfield><br/>
<s:submit value="提交"></s:submit>
</s:form>
</body>
</html>
测试:
======》访问 http://localhost:8080/struts4/demo
6.2 Struts2标签自动从值栈对象中获取数据(数据回显)
===>> 通过标签的name属性取值(只能获取值栈对象中的list栈中数据)
UserAction.java
public class UserAction extends ActionSupport{
/**
* 1.通过值栈对象操作list集合
* @return
*/
public String demo() {
//key:xxx,value:vvv。放入值栈对象中的map集合中
ActionContext ac = ActionContext.getContext();
ValueStack vs = ac.getValueStack();
UserEntity user=new UserEntity();
user.setAge(12);
user.setName("小白");
user.setPwd("121");
vs.push(user);
return "index";
}
}
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="xxxx" extends="struts-default">
<global-results>
<result name="input">/register.jsp</result>
</global-results>
<action name="demo" class="org.jsft.demo.UserAction" method="demo">
<result name="index">/index.jsp</result>
</action>
</package>
</struts>
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<s:debug></s:debug>
<!-- 表单 -->
<s:form action="./demo" method="post" theme="simple">
用户名:<s:textfield name="name" ></s:textfield><br/>
密码:<s:textfield name="pwd" ></s:textfield><br/>
<s:submit value="提交"></s:submit>
</s:form>
</body>
</html>
测试:
======》访问 http://localhost:8080/struts4/demo