目录
4.往值栈中压对象 不推荐写法:set 不过有个句柄也好理解了,比较像el
5.往值栈中压入对象(☆难点:action类也有user属性,具体方法也压栈了一个user)
success.jsp7 struts2迭代标签取值(不推荐)
ognl.NoSuchPropertyException解决办法
今日资料下载: 直接下载struts2_3.zip 网盘备份下载
注意点:
vs.push(object)方法 每次只能将object压入值栈root区的栈顶(本质是一个arrayList的0位置) 因为没有key只有value呀
vs.set(key,value) 比较好,将<key,value> 存入值栈context区,也是每次压倒栈顶,若set的就是map直接压,若只有值,帮你随机生成个key,封装到map里再压栈顶
注意:使用struts的标签要引入 <%@ taglib prefix="s" uri="/struts-tags" %>
使用el/jstl需要引入标签 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
(使用el/jstl:elipse还需要导jar包,myeclipse不需要)<s:debug></s:debug>可以查看值栈结构
一、先搭建好struts2框架
测试链接和struts.xml放前面吧
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>valueStack</title>
</head>
<body>
<h3>如何获取值栈</h3>
<a href="${pageContext.request.contextPath }/vs1.action">获取值栈</a><br>
<h3>请求action往值栈压值 并传给前端 前端获取值栈中的值</h3>
<a href="${pageContext.request.contextPath }/vs1_save1.action">往值栈中压入值☆</a><br><br>
<a href="${pageContext.request.contextPath }/vs1_save2.action">往值栈中压入对象推荐push★</a><br>
<a href="${pageContext.request.contextPath }/vs1_save3.action">往值栈中压入对象不推荐push</a><br>
<a href="${pageContext.request.contextPath }/vs1_save4.action">往值栈中压入对象(☆难点:action类也有user属性,方法也压栈了一个user)</a><br><br>
<a href="${pageContext.request.contextPath }/vs1_save5.action">往值栈中压入集合 不推荐push</a><br>
<a href="${pageContext.request.contextPath }/vs1_save6.action">往值栈中压入集合 推荐set★</a><br><br>
<a href="${pageContext.request.contextPath }/vs1_save7.action">往Context域中压入值(了解)</a><br><br>
<a href="${pageContext.request.contextPath }/vs1_save8.action">el表达式获取值栈的值★★</a><br>
</body>
</html>
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="valuestack1" namespace="/" extends="struts-default">
<!-- 获取值栈 -->
<action name="vs1" class="cn.ahpu.action.ValueStack1Action"/>
<!-- 压栈 从值栈中获取值 -->
<action name="vs1_*" class="cn.ahpu.action.ValueStack1Action" method="{1}">
<result name="success" type="dispatcher">/success.jsp</result>
</action>
</package>
</struts>
User.java
package cn.ahpu.domain;
public class User {
private String username;
private String password;
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 User(String username, String password) {
this.username = username;
this.password = password;
}
public User() {}
}
二、往值栈压值,前端如何获取值
1.获取值栈
ValueStack1Action.java
/**
* 主要演示获取值栈
*/
@Override
public String execute() throws Exception {
// System.out.println("........");
/**
* 获取值栈 servlet的api完全解耦合却不推荐用的哪个api ActionContext 获取值栈却一直用它
* ActionContext和ValueStack共享一个Context因此可以通过ActionContext.getContext()获得
*/
ValueStack vs = ActionContext.getContext().getValueStack();
System.out.println(vs);
vs.push("天河");//root栈顶就是字符串"天河"了
vs.set("msg", "紫英");//root栈顶是一个map<"msg","紫英">了 栈顶下一个位置为字符串"天河"
vs.set("info","梦璃");//栈顶已经是个map了,直接存到栈顶的那个map中了,多一项键值对而已
//都是放到root栈顶 本质一个arrylist
return SUCCESS;//转发到页面 以把数据传到jsp页面
}
2.往值栈压普通值
action2
public String save1(){
ValueStack vs = ActionContext.getContext().getValueStack();
vs.push("天河");
vs.set("msg", "紫英");
vs.set("info","梦璃");
return SUCCESS;
}
success.jsp2
<h4>往值栈中压入普通值:push eg: vs.push("天河");</h4>
<!-- [0]表示从栈顶开始向下查找打印 [1]表示从栈顶下一个开始向下打印 -->
<s:property value="[1].top"/><!-- 天河先压 在1位置 -->
<h4>往值栈中压入普通值:set eg: vs.set("msg", "紫英"); vs.set("info","梦璃");</h4>
<s:property value="[0].top.msg"/><!-- map后压 在0栈顶位置 -->
<s:property value="[0].top.info"/>
3.往值栈中压对象 推荐写法:push() ★
action3
public String save2(){
ValueStack vs = ActionContext.getContext().getValueStack();
User user=new User("天河", "163");
vs.push(user);
return SUCCESS;
}
success.jsp3
<hr>
<h4>往值栈中压入对象推荐写法★:push eg:vs.push(user);</h4>
<s:property value="[0].top.username"/>
<s:property value="[0].top.password"/>
<br>直接省略[0].top(就是user)写法也行 因此压对象以后都用push findValue方法从栈顶往下找,匹配找到的第一个,而user就在栈顶<br>
<s:property value="username"/>
<s:property value="password"/>
4.往值栈中压对象 不推荐写法:set 不过有个句柄也好理解了,比较像el
action4
public String save3(){
ValueStack vs = ActionContext.getContext().getValueStack();
User user=new User("天河", "163");
vs.set("user", user);
return SUCCESS;
}
success.jsp4
<hr>
<h4>往值栈中压入对象不推荐写法:set()</h4>
<s:property value="[0].top.user.username"/>
<s:property value="[0].top.user.password"/>
<br>(直接省略[0].top(就是那个map)写法也行)<br>
<s:property value="user.username"/><!-- 注意理解此处的user是set中的key"user" -->
<s:property value="user.password"/>
5.往值栈中压入对象(☆难点:action类也有user属性,具体方法也压栈了一个user)
action5
private User user=new User("紫英","162");
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String save4(){
ValueStack vs = ActionContext.getContext().getValueStack();
User user=new User("天河", "163");
vs.set("user", user);
return SUCCESS;
}
success.jsp5
<hr>
<h4>action属性和方法先后压栈一个user</h4>
方法在栈顶位置[0]: <s:property value="[0].top.user.username"/> <s:property value="user.password"/>
<br>action及其属性在栈顶下一个位置[1]: <s:property value="[1].top.user.username"/> ||必须显示指定[1]
6.往值栈中压入集合:push(不推荐)
action6
public String save5(){
ValueStack vs = ActionContext.getContext().getValueStack();
List<User> ulist=new ArrayList<User>();
ulist.add(new User("天河", "163"));
ulist.add(new User("紫英", "163"));
ulist.add(new User("梦璃", "162"));
vs.push(ulist);
return SUCCESS;
}
success.jsp6
<hr>
<h4>往值栈中压入集合:push(不推荐)<br> </h4>
<s:property value="[0].top[0].username"/>
<s:property value="[0].top[1].username"/>
<s:property value="[0].top[2].username"/>
<s:property value="username"/><!-- 取不到 所以很麻烦-->
7.往值栈中压入集合:set(推荐★)
action7
public String save6(){
ValueStack vs = ActionContext.getContext().getValueStack();
List<User> ulist=new ArrayList<User>();
ulist.add(new User("天河", "163"));
ulist.add(new User("紫英", "163"));
ulist.add(new User("梦璃", "162"));
vs.set("ulist", ulist);
return SUCCESS;
}
success.jsp7 struts2迭代标签取值(不推荐)
<hr>
<h4>往值栈中压入集合:set(推荐★)<br> </h4>
直接取ulist: <s:property value="ulist"/><br>
<s:property value="[0].top.ulist[0].username"/><!-- [0].top就是ulist -->
<s:property value="ulist[1].username"/><!-- 有ulist做句柄就可以简写了 -->
<s:property value="ulist[2].username"/>
<!--
属性
* value 要迭代的集合,需要从值栈中获取
* var 迭代过程中,遍历的对象
* var编写上,把迭代产生的对象默认压入到context栈中,从context栈取值,加#号
* var不编写,默认把迭代产生的对象压入到root栈中
-->
<br><br>迭代标签获取值:<br>
编写var的属性,默认压入context栈:
<s:iterator value="ulist" var="u">
<s:property value="#u.username"/>
<s:property value="#u.password"/> ||
</s:iterator>
<br>不编写var的属性 默认压入root栈(较好):
<s:iterator value="ulist">
<s:property value="username"/>
<s:property value="password"/> ||
</s:iterator>
8.往值栈context域中压入值(了解)
action8
public String save7(){
HttpServletRequest request = ServletActionContext.getRequest();
request.setAttribute("msg", "天河");
request.getSession().setAttribute("msg", "紫英");
return SUCCESS;
}
success.jsp8 访问context域必加#
<hr>
<h4>往Context域中压入值(了解)</h4>
<s:property value="#request.msg"/>
<s:property value="#session.msg"/>
9.el表达式获取值栈的值★★
public String save8(){
ValueStack vs = ActionContext.getContext().getValueStack();
List<User> ulist=new ArrayList<User>();
ulist.add(new User("天河", "163"));
ulist.add(new User("紫英", "163"));
ulist.add(new User("梦璃", "162"));
vs.set("ulist", ulist);//集合都要set方法压栈
return SUCCESS;
}
success.jsp9
<hr>
<h4>el表达式获取值栈的值★★</h4>
<c:forEach items="${ulist }" var="user">
${user.username } ${user.password } ||
</c:forEach>
<hr>
汇总:
ValueStack1Action.java
package cn.ahpu.action;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;
import cn.ahpu.domain.User;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
public class ValueStack1Action extends ActionSupport {
/**
* 主要演示获取值栈
*/
@Override
public String execute() throws Exception {
// System.out.println("........");
/**
* 获取值栈 servlet的api完全解耦合却不推荐用的哪个api ActionContext 获取值栈却一直用它
* ActionContext和ValueStack共享一个Context因此可以通过ActionContext.getContext()获得
*/
ValueStack vs = ActionContext.getContext().getValueStack();
System.out.println(vs);
vs.push("天河");//root栈顶就是字符串"天河"了
vs.set("msg", "紫英");//root栈顶是一个map<"msg","紫英">了 栈顶下一个位置为字符串"天河"
vs.set("info","梦璃");//栈顶已经是个map了,直接存到栈顶的那个map中了,多一项键值对而已
//都是放到root栈顶 本质一个arrylist
return SUCCESS;//转发到页面 以把数据传到jsp页面
}
/**
* 演示从值栈中获取值
* 往值栈压普通值
*/
public String save1(){
ValueStack vs = ActionContext.getContext().getValueStack();
vs.push("天河");
vs.set("msg", "紫英");
vs.set("info","梦璃");
return SUCCESS;
}
/**
* 演示从值栈中获取值
* 往值栈中压对象 推荐写法:push() ★
*/
public String save2(){
ValueStack vs = ActionContext.getContext().getValueStack();
User user=new User("天河", "163");
vs.push(user);
return SUCCESS;
}
/**
* 演示从值栈中获取值
* 往值栈中压对象 不推荐写法:set
*/
public String save3(){
ValueStack vs = ActionContext.getContext().getValueStack();
User user=new User("天河", "163");
vs.set("user", user);
return SUCCESS;
}
/**
* 演示从值栈中获取值
* 往值栈中压对象 action类页压栈,就在vs.set或push之前也即[1]位置,此时[0]和[1]位置就都有User了
*/
private User user=new User("紫英","162");
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String save4(){
ValueStack vs = ActionContext.getContext().getValueStack();
User user=new User("天河", "163");
vs.set("user", user);
return SUCCESS;
}
/**
* 演示从值栈中获取值
* 压栈集合 push 不推荐
*/
public String save5(){
ValueStack vs = ActionContext.getContext().getValueStack();
List<User> ulist=new ArrayList<User>();
ulist.add(new User("天河", "163"));
ulist.add(new User("紫英", "163"));
ulist.add(new User("梦璃", "162"));
vs.push(ulist);
return SUCCESS;
}
/**
* 演示从值栈中获取值
* 压栈集合 set 推荐 ★
*/
public String save6(){
ValueStack vs = ActionContext.getContext().getValueStack();
List<User> ulist=new ArrayList<User>();
ulist.add(new User("天河", "163"));
ulist.add(new User("紫英", "163"));
ulist.add(new User("梦璃", "162"));
vs.set("ulist", ulist);
return SUCCESS;
}
/**
* 演示从值栈中获取值 上面所有方法都是root域中压值 最后一个简单演示往context域中压入值
*/
public String save7(){
HttpServletRequest request = ServletActionContext.getRequest();
request.setAttribute("msg", "天河");
request.getSession().setAttribute("msg", "紫英");
return SUCCESS;
}
/**
* 超级重点 使用el表达式获取值栈中的值 ★★
*/
public String save8(){
ValueStack vs = ActionContext.getContext().getValueStack();
List<User> ulist=new ArrayList<User>();
ulist.add(new User("天河", "163"));
ulist.add(new User("紫英", "163"));
ulist.add(new User("梦璃", "162"));
vs.set("ulist", ulist);//集合都要set方法压栈
return SUCCESS;
}
}
success.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>valueStack</title>
</head>
<body>
<h4>往值栈中压入普通值:push eg: vs.push("天河");</h4>
<!-- [0]表示从栈顶开始向下查找打印 [1]表示从栈顶下一个开始向下打印 -->
<s:property value="[1].top"/><!-- 天河先压 在1位置 -->
<h4>往值栈中压入普通值:set eg: vs.set("msg", "紫英"); vs.set("info","梦璃");</h4>
<s:property value="[0].top.msg"/><!-- map后压 在0栈顶位置 -->
<s:property value="[0].top.info"/>
<hr>
<h4>往值栈中压入对象推荐写法★:push eg:vs.push(user);</h4>
<s:property value="[0].top.username"/>
<s:property value="[0].top.password"/>
<br>(直接省略[0].top(就是user)写法也行 因此压对象以后都用push findValue方法从栈顶往下找,匹配找到的第一个,而user就在栈顶)<br>
<s:property value="username"/>
<s:property value="password"/>
<hr>
<h4>往值栈中压入对象不推荐写法:set()</h4>
<s:property value="[0].top.user.username"/>
<s:property value="[0].top.user.password"/>
<br>(直接省略[0].top(就是那个map)写法也行 )<br>
<s:property value="user.username"/><!-- 注意理解此处的user是set中的key"user" -->
<s:property value="user.password"/>
<hr>
<h4>action属性和方法先后压栈一个user</h4>
方法在栈顶位置[0]: <s:property value="[0].top.user.username"/> <s:property value="user.password"/>
<br>action及其属性在栈顶下一个位置[1]: <s:property value="[1].top.user.username"/> ||必须显示指定[1]
<hr>
<h4>往值栈中压入集合:push(不推荐)<br> </h4>
<s:property value="[0].top[0].username"/>
<s:property value="[0].top[1].username"/>
<s:property value="[0].top[2].username"/>
<s:property value="username"/><!-- 取不到 -->
<hr>
<h4>往值栈中压入集合:set(推荐★)<br> </h4>
直接取ulist: <s:property value="ulist"/><br>
<s:property value="[0].top.ulist[0].username"/><!-- [0].top就是ulist -->
<s:property value="ulist[1].username"/><!-- 有ulist做句柄就可以简写了 -->
<s:property value="ulist[2].username"/>
<!--
属性
* value 要迭代的集合,需要从值栈中获取
* var 迭代过程中,遍历的对象
* var编写上,把迭代产生的对象默认压入到context栈中,从context栈取值,加#号
* var不编写,默认把迭代产生的对象压入到root栈中
-->
<br><br>迭代标签获取值:<br>
编写var的属性,默认压入context栈:
<s:iterator value="ulist" var="u">
<s:property value="#u.username"/>
<s:property value="#u.password"/> ||
</s:iterator>
<br>不编写var的属性 默认压入root栈(较好):
<s:iterator value="ulist">
<s:property value="username"/>
<s:property value="password"/> ||
</s:iterator>
<hr>
<h4>往Context域中压入值(了解)</h4>
<s:property value="#request.msg"/>
<s:property value="#session.msg"/>
<hr>
<h4>el表达式获取值栈的值★★</h4>
<c:forEach items="${ulist }" var="user">
${user.username } ${user.password } ||
</c:forEach>
<hr>
<s:debug></s:debug>
</body>
</html>
三、重点模板总结
需求:请求action往值栈压值,全部用最简单的方式 传给前端 前端获取值栈中的值 全部用最简单的el表达式jstl标签库获取值栈的值
1、搭建struts2环境
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<!-- struts2核心过滤器 前端控制器 必须配置 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
2.struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="valuestack1" namespace="/" extends="struts-default">
<!-- 压栈 从值栈中获取值 -->
<action name="vs_*" class="cn.ahpu.action.ValueStackAction" method="{1}">
<result name="success" type="dispatcher">/success.jsp</result>
</action>
</package>
</struts>
3.辅助javabean
User.java
package cn.ahpu.domain;
public class User {
private String username;
private String password;
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 User(String username, String password) {
this.username = username;
this.password = password;
}
public User() {}
}
4.Action类
ValueStackTestAction.java
package cn.ahpu.action;
import java.util.ArrayList;
import java.util.List;
import cn.ahpu.domain.User;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
public class ValueStackTestAction extends ActionSupport {
/**
* 1.push普通值
*/
public String save1(){
ValueStack vs = ActionContext.getContext().getValueStack();
vs.push("百里屠苏");
return SUCCESS;
}
/**
* 2.set普通值
*/
public String save2(){
ValueStack vs = ActionContext.getContext().getValueStack();
vs.set("msg","百里屠苏");
return SUCCESS;
}
/**
* 3.push 对象
*/
public String save3(){
ValueStack vs = ActionContext.getContext().getValueStack();
User user=new User("百里屠苏", "123");
vs.push(user);
return SUCCESS;
}
/**
* 4.set 集合
*/
public String save4(){
ValueStack vs = ActionContext.getContext().getValueStack();
List<User> ulist=new ArrayList<>();
ulist.add(new User("百里屠苏", "123"));
ulist.add(new User("风晴雪", "456"));
ulist.add(new User("欧阳少恭", "789"));
vs.set("ulist", ulist);
return SUCCESS;
}
/**
* 5.set action也压栈 直接拿action的属性 尽量不重名
* ☆ 注意struts2的属性名必须以2个小写字母开头
*/
private String acVar="actionVar";
private User acUser=new User("actionUser","110");
public String getAcVar() {
return acVar;
}
public void setAcVar(String acVar) {
this.acVar = acVar;
}
public User getAcUser() {
return acUser;
}
public void setAcUser(User acUser) {
this.acUser = acUser;
}
public String save5(){
ValueStack vs = ActionContext.getContext().getValueStack();
User user=new User("百里屠苏", "123");
vs.push(user);
return SUCCESS;
}
}
5.前端取值(重点掌握el表达式)
头部加上:
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
success.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>valueStack</title>
</head>
<body>
<h4>1.push普通值</h4>
标签: <s:property value="[0].top"/><br>
el表达式: 无法获取
<hr>
<h4>2.set普通值</h4>
标签: <s:property value="[0].top.msg"/>--<s:property value="msg"/><br>
el表达式: ${msg } ★(可以直接获取 普通值都要set吧)
<hr>
<h4>3.push对象</h4>
标签: <s:property value="username"/>--<s:property value="password"/><br><!-- 省略[0].top. -->
el表达式: ${username }--${password }
<hr>
<h4>4.set集合</h4>
标签: <s:property value="ulist[0].username"/>--<s:property value="ulist[1].username"/><br><!-- 省略[0].top. -->
el表达式:
<c:forEach items="${ulist }" var="u">
${u.username }--${u.password }
</c:forEach>
<br>标签迭代:
<s:iterator value="ulist">
<s:property value="username"/>--<s:property value="password"/>
</s:iterator>
<hr>
<h4>5.直接拿action属性</h4>
标签: action类:<s:property value="[1].top"/>
<br>具体属性值: <s:property value="[1].top.acVar"/>--<s:property value="[1].top.acUser.username"/><br>
el表达式:${acVar }--${acUser.username }--${acUser.password }||${username }--${password }<!-- push对象不需要加user. -->
<br><i>(el表达式可以直接拿Action的属性值了,只要不重名,就没冲突 太强了 深刻掌握!!★★)</i>
<hr>
<s:debug></s:debug>
</body>
</html>
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>valueStack</title>
</head>
<body>
<h3>请求action往值栈压值 并传给前端 前端获取值栈中的值 全部用el表达式获取值栈的值</h3>
<a href="${pageContext.request.contextPath }/vs_save1.action">1.往值栈中push普通值</a><br>
<a href="${pageContext.request.contextPath }/vs_save2.action">2.往值栈中set普通值</a><br>
<a href="${pageContext.request.contextPath }/vs_save3.action">3.往值栈中push对象</a><br>
<a href="${pageContext.request.contextPath }/vs_save4.action">4.往值栈中set集合</a><br>
<a href="${pageContext.request.contextPath }/vs_save5.action">5.action类默认压栈 直接取action的属性值</a><br>
</body>
</html>
6.测试运行
合并整理下
----------------------------------------------------------------
/**
* 1.push普通值
*/
public String save1(){
ValueStack vs = ActionContext.getContext().getValueStack();
vs.push("百里屠苏");
return SUCCESS;
}
<h4>1.push普通值</h4>
标签: <s:property value="[0].top"/><br>
el表达式: 无法获取
<hr>
----------------------------------------------------------------
/**
* 2.set普通值
*/
public String save2(){
ValueStack vs = ActionContext.getContext().getValueStack();
vs.set("msg","百里屠苏");
return SUCCESS;
}
<h4>2.set普通值</h4>
标签: <s:property value="[0].top.msg"/>--<s:property value="msg"/><br>
el表达式: ${msg } ★(可以直接获取 普通值都要set吧)
<hr>
----------------------------------------------------------------
/**
* 3.push 对象
*/
public String save3(){
ValueStack vs = ActionContext.getContext().getValueStack();
User user=new User("百里屠苏", "123");
vs.push(user);
return SUCCESS;
}
<h4>3.push对象</h4>
标签: <s:property value="username"/>--<s:property value="password"/><br><!-- 省略[0].top. -->
el表达式: ${username }--${password }
<hr>
----------------------------------------------------------------
/**
* 4.set 集合
*/
public String save4(){
ValueStack vs = ActionContext.getContext().getValueStack();
List<User> ulist=new ArrayList<>();
ulist.add(new User("百里屠苏", "123"));
ulist.add(new User("风晴雪", "456"));
ulist.add(new User("欧阳少恭", "789"));
vs.set("ulist", ulist);
return SUCCESS;
}
<h4>4.set集合</h4>
标签: <s:property value="ulist[0].username"/>--<s:property value="ulist[1].username"/><br><!-- 省略[0].top. -->
el表达式:
<c:forEach items="${ulist }" var="u">
${u.username }--${u.password }
</c:forEach>
<br>标签迭代:
<s:iterator value="ulist">
<s:property value="username"/>--<s:property value="password"/>
</s:iterator>
<hr>
----------------------------------------------------------------
/**
* 5.set action也压栈 直接拿action的属性 尽量不重名
* ☆ 注意struts2的属性名必须以2个小写字母开头
*/
private String acVar="actionVar";
private User acUser=new User("actionUser","110");
public String getAcVar() {
return acVar;
}
public void setAcVar(String acVar) {
this.acVar = acVar;
}
public User getAcUser() {
return acUser;
}
public void setAcUser(User acUser) {
this.acUser = acUser;
}
public String save5(){
ValueStack vs = ActionContext.getContext().getValueStack();
User user=new User("百里屠苏", "123");
vs.push(user);
return SUCCESS;
}
<h4>5.直接拿action属性</h4>
标签: action类:<s:property value="[1].top"/>
<br>具体属性值: <s:property value="[1].top.acVar"/>--<s:property value="[1].top.acUser.username"/><br>
el表达式:${acVar }--${acUser.username }--${acUser.password }||${username }--${password }<!-- push对象不需要加user. -->
<br><i>(el表达式可以直接拿Action的属性值了,只要不重名,就没冲突 太强了 深刻掌握!!★★)</i>
<hr>
----------------------------------------------------------------
ognl.NoSuchPropertyException解决办法
定义属性:private String aVar="我是action属性";或者private User aUser=new User("action的User","110");报错
原因:
在bean中的属性定义时,必须将前2个字母写为小写,sName是不符合规定的,struts2将找不到这样的名字的属性,而stName就可以。当然这个属性是private的,如果是public,无论什么形式的命名都是可以访问的。
解决:
修改属性名后重启tomcat