目錄
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