Struts2

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)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 概述 什么是Struts2的框架Struts2是Struts1的下一代產(chǎn)品,是在 struts1和WebWork的...
    inke閱讀 2,337評(píng)論 0 50
  • action中如何接受頁面?zhèn)鬟^來的參數(shù) 第一種情況:(同名參數(shù)) 例如:通過頁面要把id=1 name=tom a...
    清楓_小天閱讀 3,285評(píng)論 1 22
  • 1、struts2工作流程 Struts 2框架本身大致可以分為3個(gè)部分: 核心控制器FilterDispatch...
    重山楊閱讀 1,604評(píng)論 0 38
  • 嗯 突然聽到這首歌 矯情的情緒就像海水一樣都涌了出來 對(duì)的 我所有的文字都是毫無頭緒 無病呻吟 我...
    孫四歲閱讀 386評(píng)論 0 0
  • 高考后就沒有再寫過一千字以上的文章了,覺得應(yīng)該鼓勵(lì)下自己。 今天通過老師對(duì)馬斯洛需求理論五要素的...
    李瑞英mile閱讀 217評(píng)論 0 4

友情鏈接更多精彩內(nèi)容