struts2介紹
概括
struts2是J2EE的比較流行的框架,對(duì)JSP/servlet進(jìn)行了封裝,應(yīng)用于面向WEB開發(fā)的項(xiàng)目。
struts是MVC設(shè)計(jì)模式的一種解決方案
Struts2是基于MVC的Web應(yīng)用框架
Struts2=Struts1的知名度和市場(chǎng)+WebWork的技術(shù)
實(shí)現(xiàn)MVC模式,結(jié)構(gòu)清晰
豐富的標(biāo)簽(tag)
通過配置文件頁面導(dǎo)航,便于后期維護(hù)
與Servlet API松耦合,便于測(cè)試
下載
http://struts.apache.org
Projects -- > struts
http://archive.apache.org/dist/struts/binaries/
功能介紹
數(shù)據(jù)輸入校驗(yàn)。
Struts標(biāo)簽用于頁面開發(fā)。
可擴(kuò)展性編程。
采用攔截器實(shí)現(xiàn)AOP功能。
國(guó)際化和本地化。
文件上傳下載。
表單重復(fù)提交校驗(yàn)
struts2和struts1的區(qū)別
1)Action實(shí)現(xiàn):struts1繼承抽象的父類,struts2不需要。
2)Action實(shí)例化:struts1中Action是單例模式,Struts2為每一個(gè)請(qǐng)求創(chuàng)建一個(gè)Action實(shí)例。
3)與jsp/Servlet耦合:struts1在調(diào)用傳統(tǒng)的jsp/servletAPI,但struts2可以調(diào)用jsp/servlet的API(不推薦),但重新封裝了其他的API(與jsp/servlet無關(guān)),實(shí)現(xiàn)解耦。
4)測(cè)試方面:因?yàn)镾truts1仍然調(diào)用servlet的API,因此測(cè)試必須依賴于web服務(wù)器,但Struts2克通過實(shí)例化,方法調(diào)用的方式測(cè)試。
5)表達(dá)式語言:struts1整合了JSTL,struts2則整合了 更為強(qiáng)大的OGNL表達(dá)式。
6)struts2與struts1除了命名之外,其實(shí)沒有多大關(guān)系。
目錄結(jié)構(gòu)
apps:基于Struts2的示例應(yīng)用
docs:Struts2開發(fā)的各類幫助文檔
lib:核心類庫及第三方插件類庫
requied-lib:Struts 2開發(fā)常用的jar文件
src:Struts2框架的源代碼
使用
1.導(dǎo)入jar包
struts2-core-2.3.4.1.jar Struts2的核心包
xwork-core-2.3.4.1.jar xwork的核心包
commons-io-2.0.1.jar 支持IO讀寫操作
commons-fileupload-1.2.2.jar 支持文件的上傳和下載
ognl-3.0.5.jar 支持OGNL表達(dá)式
freemarker-2.3.19.jar 基于模板生成文本輸出的通用工具/標(biāo)簽庫模板包
javassist-3.11.0.GA.jar 支持JAVA字節(jié)碼操作
commons-lang3-3.1.jar 對(duì)java.lang包擴(kuò)展
2.配置struts2的核心過濾器
在web.xml中配置
<filter>
<filter-name>struts2</filter-name>
<!-- 核心控制器,負(fù)責(zé)攔截用戶的請(qǐng)求,根據(jù)請(qǐng)求的不同,分發(fā)給相應(yīng)的Action處理 -->
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<!-- 將全部請(qǐng)求定位到指定的Struts 2過濾器中 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
3.truts2的配置文件
在src目錄下
默認(rèn)struts.xml
4.編寫Action
5.在struts配置文件中配置action
Action
作用
處理請(qǐng)求
實(shí)現(xiàn)業(yè)務(wù)邏輯
返回result決定結(jié)果視圖
實(shí)現(xiàn)方式
1.普通的Java類
2.實(shí)現(xiàn)Action接口
3.繼承ActionSupport類
普通的Java類
public class OneAction{
public String execute() throws Exception {
System.out.println("訪問到了");
//返回的字符串 對(duì)應(yīng) result的name屬性
return "success";
}
}
實(shí)現(xiàn)Action接口
public class OneAction implements Action{
@Override
public String execute() throws Exception {
System.out.println("訪問到了");
//返回的字符串 對(duì)應(yīng) result的name屬性
return "success";
}
}
繼承ActionSupport類
public class OneAction extends ActionSupport{
private static final long serialVersionUID = 2245233853322624873L;
//action中默認(rèn)調(diào)用的方法就是execute方法
@Override
public String execute() throws Exception {
System.out.println("訪問到了");
//返回的字符串 對(duì)應(yīng) result的name屬性
return "success";
}
}
配置
<action name="one" class="com.shuai.test.OneAction" method="execute">
<result name="success">/info.jsp</result>
</action>
Struts配置文件
基礎(chǔ)配置
這個(gè)配置文件需要到struts的源碼中去搜索,隨便一個(gè)就可以。
<?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>
</struts>
內(nèi)容
<package name="shuai" extends="struts-default" namespace="/shuai">
<action name="" class="" method="">
<result name=""></result>
</action>
</package>
說明
package
說明
包,管理action的路徑
name
包名
作用:給其它包去繼承
注意:包名必須要唯一,否則啟動(dòng)會(huì)報(bào)錯(cuò)
namespace
命名空間
可以對(duì)路徑進(jìn)行管理
是url的一部分
默認(rèn)是/
如果是 /test 訪問路徑 = /test/actionName
extends
繼承
自定義的包,必須要繼承 struts-default
struts-default.xml
文件目錄 struts2-core-xxx.jar/struts-default.xml
result-types : 返回值類型
interceptors : 攔截器
abstract
默認(rèn)是false,如果是true表示是一個(gè)抽象包,即里面不能有action的定義。
action
說明
是一個(gè)控制器
作用:配置訪問路徑與處理action的映射關(guān)系
name
訪問路徑
控制器的名稱,是url的一部分
class
控制器實(shí)際路徑
訪問路徑對(duì)應(yīng)action類的全名 可以不寫 默認(rèn)是ActionSupport
默認(rèn)的class寫法用來做頁面跳轉(zhuǎn)
WebContent目錄下是 /hello.jsp
WEB-INF目錄下是 /WEB-INF/hello.jsp
默認(rèn)的class在 struts-default.xml中配置了 <default-class-ref class="com.opensymphony.xwork2.ActionSupport" />
修改默認(rèn)執(zhí)行的Action類 一般不會(huì)做修改
<default-class-ref class="com.shuai.struts2.action.six.MyDefaultAction"></default-class-ref>
method
執(zhí)行的方法,默認(rèn)是execute
可以省略不寫
result
說明
是結(jié)果集
配置action中處理請(qǐng)求的方法,返回的結(jié)果視圖標(biāo)記對(duì)應(yīng)的跳轉(zhuǎn)資源
name
是結(jié)果的名稱,通過action動(dòng)作的返回值來指定。
action處理方法的返回值
文本值
是結(jié)果視圖
type
設(shè)置結(jié)果視圖的類型和跳轉(zhuǎn)方式
轉(zhuǎn)發(fā) : dispatcher 默認(rèn)
重定向 : redirect
這兩個(gè)值都在struts-default.xml 中result-types中有定義
struts2訪問過程
http://localhost:8080/struts2/test/six1
1.先找struts.xml配置文件
2.在配置文件中找命名空間/test 注意:這個(gè)地方會(huì)按照層級(jí)去找
/a/b/c/six 查找機(jī)制
首先在/a/b/c/中找six
然后在/a/b/中找six
然后再/a/中找six
然后再/中找six
如果沒有就報(bào)錯(cuò)
3.在命名空間中找action的six1
4.執(zhí)行action中的方法
5.在配置文件中找result返回值
6.找到頁面進(jìn)行返回
Action細(xì)節(jié)
struts2的加載順序
default.properties --> struts-default.xml --> struts.xml ---> *.xml
其它注意
每次訪問action的內(nèi)存地址都是會(huì)改變的
action是多例的
servlet,filter,listener是單例的
struts1中的action是單例的
請(qǐng)求參數(shù)封裝
<form action="one" method="post">
<!-- 普通屬性方式 -->
<input type="text" name="name"/>
<!-- 對(duì)象屬性方式 -->
<input type="text" name="student.username">
<!-- ModelDriven方式 -->
<input type="text" name="username">
<input type="submit" />
</form>
屬性方式
public class OneAction{
//普通屬性方式
private String name;
//對(duì)象屬性方式
private Student student;
public String execute() throws Exception {
return "success";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
}
對(duì)象方式
public class UserAction{
private Student student;
public String execute() throws Exception {
System.out.println("user-action");
System.out.println(student);
return "success";
}
public void setStudent(Student student){
this.student = student;
}
public Student getStudent(){
return this.student;
}
}
ModelDriven方式
public class UserAction implements ModelDriven<Student>{
private Student student = new Student();
public String execute() throws Exception {
System.out.println("user-action");
System.out.println(student);
return "success";
}
@Override
public Student getModel() {
return student;
}
}
通配符
與后邊的{1}是對(duì)應(yīng)關(guān)系
eight_* 中 {1}代表這個(gè)*
eight_*_* 中{2}代表第二個(gè)*
<action name="eight_*" class="com.shuai.struts2.action.EightAction" method="{1}">
<!-- 指代跟方法名相同的jsp頁面 -->
<result>/{1}.jsp</result>
</action>
按模塊拆分struts.xml
struts-article.xml
<package name="article" namespace="/article" extends="struts-default">
<action name="one" class="com.shuai.test.ArticleAction" method="execute">
<result name="success">/article.jsp</result>
</action>
</package>
struts-user.xml
<package name="user" namespace="/user" extends="struts-default">
<action name="one" class="com.shuai.test.UserAction" method="execute">
<result name="success">/user.jsp</result>
</action>
</package>
struts.xml
<struts>
<constant name="struts.i18n.encoding" value="UTF-8"></constant>
<include file="struts-user.xml"></include>
<include file="struts-article.xml"></include>
</struts>
訪問Servlet API(Request/Session/Application)的方式
第一種方式
ActionContext context = ActionContext.getContext();
//保存到request域
Map<String,Object> request = (Map<String,Object>)context.get("request");
request.put("request_data", "request_data_message");
//保存到session域
Map<String,Object> session = (Map<String,Object>)context.get("session");
session.put("session_data", "session_data_message");
//保存到application域
Map<String,Object> application = (Map<String,Object>)context.get("application");
application.put("application_data", "application_data_message");
第二種方式-有耦合
//保存到request域
HttpServletRequest request = ServletActionContext.getRequest();
request.setAttribute("request_data", "request_data_message");
//保存到session域
HttpSession session = request.getSession();
session.setAttribute("session_data", "session_data_message");
//保存到application域
ServletContext context = ServletActionContext.getServletContext();
context.setAttribute("application_data", "application_data_message");
第三種方式
public class ElevenAction extends ActionSupport implements RequestAware,SessionAware,ApplicationAware{
private Map<String, Object> application;
private Map<String, Object> session;
private Map<String, Object> request;
@Override
public void setRequest(Map<String, Object> request) {
this.request = request;
}
@Override
public void setSession(Map<String, Object> session) {
this.session = session;
}
@Override
public void setApplication(Map<String, Object> application) {
this.application = application;
}
}
亂碼問題
POST方式GBK編碼
項(xiàng)目統(tǒng)一編碼GBK
<constant name="struts.i18n.encoding" value="GBK"></constant>
POST方式UTF-8編碼
項(xiàng)目統(tǒng)一編碼UTF-8
<constant name="struts.i18n.encoding" value="UTF-8"></constant>
POST方式其它
項(xiàng)目統(tǒng)一編碼GBK
<constant name="struts.i18n.encoding" value="UTF-8"></constant>
GET方法UTF-8編碼
項(xiàng)目統(tǒng)一編碼UTF-8
<constant name="struts.i18n.encoding" value="UTF-8"></constant>
tomcat/conf/server.xml配置<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8"/>
常量修改
概述
在struts2-core 里面 的 org.apache.struts2包下來 default.properties 這里面有常量配置
修改
<constant name="struts.action.extension" value="action,do,go,,"></constant>
名稱
struts.i18n.encoding=UTF-8
請(qǐng)求數(shù)據(jù)的中文處理 請(qǐng)求數(shù)據(jù)的編碼 POST請(qǐng)求
struts.action.extension=action,,
訪問后綴
struts.enable.DynamicMethodInvocation = true
是否開啟動(dòng)態(tài)方法調(diào)用,就是是否可以通過*號(hào)的方式來指代占位
http://localhost:8080/struts2/twelve1!insert 這種訪問方式是否可以
struts.multipart.maxSize=2097152
文件上傳大小的限制
默認(rèn)是2M
struts.devMode = false
開發(fā)者模式,會(huì)顯示更多的日志信息
struts.i18n.reload=false
就是改了配置文件是否需要重啟服務(wù)
struts.ui.theme=xhtml
修改struts主題 ,一般都改為simple,就是jsp頁面使用struts標(biāo)簽的時(shí)候,
頁面展示的時(shí)候,生成是html頁面是否有額外的東西。
result結(jié)果集的type類型11個(gè)類型
轉(zhuǎn)發(fā)
<result name="success" type="dispatcher">/user.jsp</result>
重定向 - 外部資源
<result name="success" type="redirect">/one.jsp</result>
<result name="success" type="redirect">/user/one</result>
配置錯(cuò)誤頁面
某個(gè)Action下的錯(cuò)誤頁面
<action name="one" class="com.shuai.test.OneAction">
<result name="error">/error.jsp</result>
</action>
全局錯(cuò)誤頁面
<global-results>
<result name="error">error.jsp</result>
</global-results>
全局未抓取的異常配置
<global-exception-mappings>
<exception-mapping result="error" exception="java.lang.Exception"/>
</global-exception-mappings>
struts-tags 標(biāo)簽
需要導(dǎo)入taglib指令:
<%@taglib uri="/struts-tags" prefix="s"%>
標(biāo)簽分類
通用標(biāo)簽
數(shù)據(jù)標(biāo)簽
控制標(biāo)簽(默認(rèn)前綴s)
UI標(biāo)簽
Ajax標(biāo)簽(默認(rèn)前綴sx)
數(shù)據(jù)標(biāo)簽
提供對(duì)各種數(shù)據(jù)訪的相關(guān)功能
<s:property>
輸出值棧及Stack Context 中所有能訪問的值
訪問對(duì)象的屬性
//value 是Action中的userName屬性
<s:property value="userName"/>
//value 是Action中的user屬性對(duì)象中的userName屬性
<s:property value="user.userName"/>
Action的成員變量存儲(chǔ)在值棧中
<s:property value="user.id"/>
訪問List集合的一個(gè)元素
<s:property value="streetsList[0]"/>
訪問List集合的第一個(gè)元素的屬性
<s:property value="streetsList[0].streetName"/>
獲取List集合的大小
<s:property value="streetsList.size()"/>
獲取List集合是否為空
<s:property value="streetsList.isEmpty()"/>
<s:debug>
在頁面上生成一個(gè)鏈接,單擊這個(gè)鏈接可以
查看值棧及Stack Context 中所有能訪問的值
<s:date>
格式化輸出一個(gè)日期
<s:set>
對(duì)設(shè)置的表達(dá)式求值,并將結(jié)果賦給特定作用域的某個(gè)變量
<s:url>
生成一個(gè)URL 地址
<s:a>
生成HTML 的<a>標(biāo)簽
<s:param>
為其他標(biāo)簽添加參數(shù)化設(shè)置
<s:include>
把其他頁面包含到當(dāng)前的頁面上
控制標(biāo)簽
用來完成流程控制,如分支流程、循環(huán)流程等
<s: if>/<s: elseif>/<s: else>
實(shí)現(xiàn)分支流程控制,它們的語意和Java中的if、else if、else相似
<s:iterator>
主要用于對(duì)集合實(shí)現(xiàn)循環(huán)訪問功能
UI標(biāo)簽
用來生成UI界面及元素
<s:form>
對(duì)應(yīng)HTML 中的<form>,用于向服務(wù)器端提交數(shù)據(jù)
<s:textfield>
對(duì)應(yīng)HTML 中的<input type="text">,即單行文本框
<s:textarea>
對(duì)應(yīng)HTML 中的<textarea>,即多行文本域
<s:submit>
對(duì)應(yīng)HTML 中的<input type="submit">,即提交表單按鈕
<s:select>
生成一個(gè)下拉框
<s:doubleselect >
生成兩個(gè)聯(lián)動(dòng)的下拉框
<s:datetimepicker>
生成一個(gè)日歷控件
interceptor攔截器(提供32個(gè),默認(rèn)執(zhí)行18個(gè))
概述
struts2是通過攔截器來完成功能的。
在struts-default.xml中定義了struts的所有攔截器 interceptors
使用攔截器 有一個(gè)攔截器棧 interceptor-stack
默認(rèn)的棧是 <interceptor-stack name="defaultStack">
struts執(zhí)行哪個(gè)攔截器棧
<default-interceptor-ref name="defaultStack"/>
攔截器與過濾器區(qū)別
過濾器
Filter 是servlet的概念
攔截所有的請(qǐng)求,jsp/servlet/html/css/js/image....
攔截器
interceptor 是struts2的概念
只攔截action請(qǐng)求
如果訪問的是jsp就不會(huì)攔截。
自定義攔截器
步驟
1.創(chuàng)建類OneInterceptor implements Interceptor
2.實(shí)現(xiàn) init/intercept/destroy方法
3.在package中配置
代碼
public class OneInterceptor implements Interceptor {
private static final long serialVersionUID = 353192690805863911L;
@Override
public void destroy() {
System.out.println("攔截器銷毀 destroy");
}
@Override
public void init() {
System.out.println("攔截器初始化");
}
@Override
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("攔截開始");
//放行,去到下一個(gè)攔截器,如果沒有下一個(gè)攔截器 就執(zhí)行action的方法
//一旦執(zhí)行了invoke方法,就說明已經(jīng)發(fā)生了資源跳轉(zhuǎn),再更改方法的返回值無效
String result = invocation.invoke();
System.out.println("攔截結(jié)束--invoke="+result);
return result;
}
}
配置
<package name="thirteen" extends="struts-default" >
<interceptors>
<!-- 自定義的攔截器 -->
<interceptor name="OneInterceptor" class="com.shuai.struts2.OneInterceptor"></interceptor>
<!-- 自定義攔截器棧 -->
<interceptor-stack name="mystatck">
<!-- 引入默認(rèn)的攔截器棧 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
<!-- 加入自己的攔截器 -->
<interceptor-ref name="OneInterceptor"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 使用自己的攔截器棧 -->
<default-interceptor-ref name="mystatck"></default-interceptor-ref>
</package>
文件上傳
單文件上傳
public class OneAction extends ActionSupport {
private static final long serialVersionUID = -5407112650267208013L;
//單文件上傳
private File file;
private String fileFileName;
private String fileContentType;
@Override
public String execute() throws Exception {
//自己打開輸入流輸出流把file寫出到某個(gè)位置即可。
System.out.println("file="+file);
System.out.println("fileFileName="+fileFileName);
System.out.println("fileContentType="+fileContentType);
return SUCCESS;
}
}
多文件上傳
public class OneAction extends ActionSupport {
private static final long serialVersionUID = -5407112650267208013L;
private File[] file;
private String[] fileFileName;
private String[] fileContentType;
@Override
public String execute() throws Exception {
for (int i = 0; i < file.length; i++) {
System.out.println("file[]=" + file[i]);
}
for (int i = 0; i < fileFileName.length; i++) {
System.out.println("fileFileName[]=" + fileFileName[i]);
}
for (int i = 0; i < fileContentType.length; i++) {
System.out.println("fileContentType[]=" + fileContentType[i]);
}
return SUCCESS;
}
}
配置文件
<action name="one" class="com.shuai.struts2.action.OneAction">
<interceptor-ref name="defaultStack">
<param name="fileUpload.allowedExtensions">txt,png,docx</param>
</interceptor-ref>
<result>/hello.jsp</result>
</action>
說明
限制允許上傳的文件類型 只能上傳這些中類型
<param name="fileUpload.allowedTypes">text/plain,image/png</param>
限制允許上傳的文件擴(kuò)展名(注意:如果與上面一起用取交集!)
<param name="fileUpload.allowedExtensions">txt,png,docx</param>
界面
<form action="one" method="post" enctype="multipart/form-data">
file:<input type="file" name="file"/><br/>
<input type="submit"/><br/>
</form>
文件下載
代碼
public class OneAction extends ActionSupport {
private static final long serialVersionUID = -5407112650267208013L;
//2.需要下載的文件名
private String fileName;
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
try {
fileName = new String(fileName.getBytes("ISO8859-1"),"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
this.fileName = fileName;
}
//1.下載方法
public String down() {
return "down"; // 注意:因?yàn)樽鱿螺d功能,返回的結(jié)果類型是“stream”
}
// 4.返回流
public InputStream getFileStream(){
File file = new File("D:\\download",this.fileName);
FileInputStream inputStream=null;
try {
inputStream = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
System.out.println("inputStream="+inputStream);
return inputStream;
}
// 5.瀏覽器顯示的文件名
public String getDownFile(){
try {
return URLEncoder.encode(fileName, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
}
配置文件
<action name="one_*" class="com.shuai.struts2.action.OneAction" method="{1}">
<result>/hello.jsp</result>
<!-- 3.下載操作 -->
<result name="down" type="stream">
<!-- 文件的類型,指定為任意二進(jìn)制類型,可以標(biāo)識(shí)任何文件 任何類型的文件 -->
<param name="contentType">application/octet-stream</param>
<!-- 對(duì)應(yīng)的是Action類中返回流的屬性! 注意:這個(gè)fileStream是action中的getFileStream方法 -->
<param name="inputName">fileStream</param>
<!-- 指定瀏覽器顯示的文件名,對(duì)應(yīng)action類中的返回文件名的屬性! 需要url編碼 注意:這個(gè)downFile是action中的getDownFile方法-->
<param name="contentDisposition">attachment;filename=${downFile}</param>
<!-- 讀取緩沖區(qū)大小 -->
<param name="bufferSize">1024</param>
</result>
</action>
OGNL表達(dá)式
概述
Object Graphic Navigation Language(對(duì)象圖導(dǎo)航語言)的縮寫,它是一個(gè)開源項(xiàng)目。
Struts2框架使用OGNL作為默認(rèn)的表達(dá)式語言。
作用
頁面取值!必須配置struts2標(biāo)簽!
頁面取值方式:
1.jsp的EL表達(dá)式
2.Struts2的Ognl表達(dá)式
使用
引入struts的jar包,必須引入ognl.jar
OGNL優(yōu)勢(shì)
1、支持對(duì)象方法調(diào)用,如xxx.doSomeSpecial();
2、支持類靜態(tài)的方法調(diào)用和值訪問,表達(dá)式的格式:
@[類全名(包括包路徑)]@[方法名|值名],例如:
@java.lang.String@format('foo %s', 'bar')
或@tutorial.MyConstant@APP_NAME;
3、支持賦值操作和表達(dá)式串聯(lián),如price=100, discount=0.8,
calculatePrice(),這個(gè)表達(dá)式會(huì)返回80;
4、訪問OGNL上下文(OGNL context)和ActionContext;
5、操作集合對(duì)象。
其它
OGNL 有一個(gè)上下文(Context)概念,說白了上下文就是一個(gè)MAP結(jié)構(gòu),它實(shí)現(xiàn)了 java.utils.Map 的接口。
Ognl的核心是OgnlContext對(duì)象
代碼
OgnlContext是一個(gè)Map
//創(chuàng)建對(duì)象
OgnlContext context = new OgnlContext();
//賦值
context.put("china", "中國(guó)");
//取值
System.out.println(context.get("china"));
往根元素設(shè)置值
User user = new User(100);
//創(chuàng)建對(duì)象
OgnlContext context = new OgnlContext();
//賦值
context.setRoot(user);
//解析
Object ognl = Ognl.parseExpression("id");
Object value = Ognl.getValue(ognl, context,context.getRoot());
System.out.println(value);
往非根元素設(shè)置值, ognl表達(dá)式取值時(shí)候,需要帶#符號(hào)
User user = new User(200);
//創(chuàng)建對(duì)象
OgnlContext context = new OgnlContext();
//賦值
context.put("user",user);
//解析
Object ognl = Ognl.parseExpression("#user.id");
Object value = Ognl.getValue(ognl, context,context.getRoot());
System.out.println(value);
總結(jié)
根元素取值
<s:property value = "id">
非根元素取值
<s:property value = "#user.name">
ognl表達(dá)式取值,如果是根元素取值不用帶#符號(hào), 非根元素取值要帶#號(hào)!
ValueStack
概述
ValueStack實(shí)際是一個(gè)接口
在Struts2中利用OGNL時(shí),實(shí)際上使用的是實(shí)現(xiàn)了該接口的OgnlValueStack類
這個(gè)類是Struts2利用OGNL的基礎(chǔ)。
特點(diǎn)
ValueStack貫穿整個(gè) Action 的生命周期(每個(gè) Action 類的對(duì)象實(shí)例都擁有一個(gè)ValueStack 對(duì)象).
相當(dāng)于一個(gè)數(shù)據(jù)的中轉(zhuǎn)站. 在其中保存當(dāng)前Action 對(duì)象和其他相關(guān)對(duì)象.
Struts2框架把 ValueStack 對(duì)象保存在名為 “struts.valueStack” 的request請(qǐng)求屬性中。
ValueStack vs1 = (ValueStack) ServletActionContext.getRequest().getAttribute("struts.valueStack");
存儲(chǔ)集合
ValueStack存儲(chǔ)對(duì)象
ObjectStack: Struts 把動(dòng)作和相關(guān)對(duì)象壓入 ObjectStack 中--List
ContextMap:
Struts 把各種各樣的映射關(guān)系(一些 Map 類型的對(duì)象) 壓入 ContextMap 中
Struts 會(huì)把下面這些映射壓入 ContextMap 中
parameters: 該 Map 中包含當(dāng)前請(qǐng)求的請(qǐng)求參數(shù)
request: 該 Map 中包含當(dāng)前 request 對(duì)象中的所有屬性
session: 該 Map 中包含當(dāng)前 session 對(duì)象中的所有屬性
application:該 Map 中包含當(dāng)前 application 對(duì)象中的所有屬性
attr: 該 Map 按如下順序來檢索某個(gè)屬性: request, session, application
值棧數(shù)據(jù)存儲(chǔ)原理
Struts每次訪問action的時(shí)候
1. 創(chuàng)建一個(gè)ActionContext對(duì)象
2. 創(chuàng)建值棧對(duì)象
把域中存放的數(shù)據(jù)、以及Action對(duì)象,放到值棧中!
這時(shí)候,值棧就有了struts運(yùn)行時(shí)期的數(shù)據(jù)!
3. 把值棧的數(shù)據(jù),拷貝一份給ActionContext!
4. 最后,把值棧放到request的請(qǐng)求中!
驗(yàn)證
其它
1.請(qǐng)求數(shù)據(jù)自動(dòng)封裝
2.數(shù)據(jù)處理
3.攔截器、自定義攔截器
4.文件上傳下載
5.Ognl表達(dá)式與struts標(biāo)簽
6.數(shù)據(jù)校驗(yàn)
7.類型轉(zhuǎn)換
8.國(guó)際化
9.模型驅(qū)動(dòng)