一、框架概述
把重複性的繁瑣的代碼封裝
起來。使程序員在編碼中把更多的精力放業務需求的分析
和理解
上面。
特點
:封裝了很多細節,程序員在使用的時候會非常簡單。
三大框架:Struts2、Spring、Hibernate
二、三層架構與Struts2
- 表現層:M model V view C control
- 業務層:Service
- 持久層:Dao data access object
Struts2
在三層架構中的位置是處於表現層
。注意它只是一個表現層框架
。
三、MVC與Struts2
M:Model 模型,封裝數據。javabean V:View 視圖,展示界面。jsp C:Controller 控制器,控制程序流程。Servlet 控制器:Servlet init(ServletConfig config) destroy() service(ServletRequest req, ServletResponse resp) 過濾器:Filter 它也可以作爲控制使用。 init(FilerConfig filterConfig) destroy() doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) Servlet能做的Filter都可以做,並且比Servlet功能更強大,它多了一個放行的功能。即:過濾器同樣也適合做控制器。 注意:Struts1的核心就是一個控制器,Struts2的核心就是一個過濾器。
四、案例中存在的一些問題
規律:
- 獲取請求正文,用戶要做什麼事情。
- 根據不同的請求,做出不同的判斷。
- 執行具體的方法代碼(
動作
)。 - 轉向頁面,展示給用戶。
缺陷:
重複性
勞動太多,具體的執行代碼也有冗餘代碼
。全是硬編碼
,像用戶要做什麼事情,對應執行什麼代碼,可以寫在配置文件
中。- 具體的代碼方法放到了
控制器
中,過於臃腫
。
五、Struts2簡介
1、Struts2概述 Struts2是Apache發行的MVC開源框架。注意:它只是表現層(MVC)框架。 2、Struts2的來歷 Struts1:也是apache開發的一套mvc的開源框架。在2005年之前非常流行。 弊端:Struts1的核心控制器就是一個Servlet。隨着使用者的增多,弊端開始出現。 Struts2:在long long ago,有一個設計超前的框架XWork,後來推出了XWork1和WebWork2。Struts2就是apache和OpenSymphony組織合併開發出來。 Struts2裏面包含了WebWork2的核心及Struts的一些特性和功能。除此之外,和Struts1沒有任何關係了。
六、搭建開發環境
- Struts2的下載和安裝
- 開發包目錄結構
- 搭建開發環境
拷貝必要jar包到classpath中(即拷貝jar包到WebRoot/WEB-INF/lib中),原則是:用哪個拷貝哪個。
注意:新老版本的區別
: 舊版本的struts2
新版本的struts2
- 建立Struts2的配置文件
at the top of classpath(在最頂層的構建路徑),建立一個默認名稱爲struts.xml的配置文件。
注意:
- 文件名大小寫。
- 創建位置。
- 該文件名稱允許修改,但是我們一般不改。
- 在web.xml中配置控制器 a、配置位置:在web.xml中 b、配置什麼: struts2已經寫好了的一個過濾器。 結論:struts2比struts1優秀的一個體現就是:它用了更爲強大的過濾器作爲控制器。
- 驗證是否搭建環境成功 部署應用後,啓動Tomcat,不報錯表示搭建成功。
- 關於struts.xml沒有提示的問題 分析原因:沒有找到對應的dtd約束文件。 解決辦法: a.開發時聯網 b.開發時不能上網咋辦呢?那就手動添加該約束文件,過程如下:
附上:上述的struts.xml和web.xml文件
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> </struts>
web.xml文件(注意:新版本的區別) if you are using struts2 version 2.5 you need to change from org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter to org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter 是的,去掉了中間.ng文件空間名,原因是在整合xwork的時候,同時簡化了不必要的包名空間。 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <display-name>day25_00_struts2Template</display-name> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app>
七、Struts2入門案例
以下步驟是日後實際開發中經常重複的。
- 建立一個訪問視圖的.jsp文件
- 在struts.xml文件中配置
- 建立動作類和動作方法
- 結果視圖頁面
- 測試
- 小問題解決 上面的模板我們做好了,就可以複製使用該模班,注意:複製該模板後,必須要修改 Web Context Root的內容,否則部署的時候會報錯(會出現跟模板名稱一樣的應用),步驟如下:在新項目上右鍵 --> Properties --> 在搜索框中輸入 Web --> 在web Context Root 中 --> Config…,如下圖所示:
八、第一個案例的執行過程
tomcat啓動,加載應用的web.xml --> tomcat實例化並初始化過濾器 --> 加載struts.xml配置文件 -->
客戶瀏覽器發送請求:hello.action --> 請求到達過濾器 --> 截取請求的動作名稱hello,並從struts.xml中查找 -->
找到後,實例化HelloAction動作類,每次都會創建新的實例 --> 調用對應的sayHello()動作方法,方法有返回值 --> 根據返回值找對應的結果視圖 --> 找到結果jsp頁面 --> 響應瀏覽器,展示結果
如下圖所示:
struts2的體系結構圖如下:
九、Struts2的配置文件的加載時機和加載順序
加載時機:當應用被tomcat加載的時候,struts2的配置文件就已經被加載過了。 加載順序:default.properties --> struts-default.xml --> struts-plugin.xml --> struts.xml --> struts.properties --> web.xml
存的是常量 攔截器、結果視圖、默認的動作類 插件 我們自己寫的 一般不用它 我們自己寫的
加載順序 | 配置文件名 | 所在位置 | 說明 |
---|---|---|---|
1 | default.properties | struts2-core-2.5.16.jar\org\apache\struts2 | 不能修改 |
2 | struts-default.xml | struts2-core-2.5.16.jar | 不能修改 |
3 | strtuts-plugin.xml | 在struts2提供的插件jar包中,名爲struts2-convention-plugin-2.5.16.jar | 不能修改 |
4 | struts.xml | 我們的應用中,該文件是web應用默認的struts配置文件 | 我們修改的:推薦修改這裏 |
5 | struts.properties | 我們的應用中,該文件是Struts的默認配置文件 | 我們修改的 |
6 | web.xml | 我們的應用中,該文件是Web應用的配置文件 | 我們修改的,可以給過濾器配置參數 |
- 注意:
1、Struts2提供了兩種配置的方式。一種是key=value的方式,即使用.properties文件。另一種是xml文件配置。我們推薦使用xml文件(因爲它能描述
層級關係
)。 2、如果多個文件配置了同一個struts2常量,則後一個文件中配置的常量值會覆蓋前面文件配置的常量值。
十、Struts2中的常量
1、常用的常量
常量定義在了default.properties
配置文件中,體現形式都是key=value
。所有的struts2應用都會用到這些常量。
常量名 | 常量值(默認值) | 說明 |
---|---|---|
struts.i18n.encoding | UTF-8 | 應用中使用的編碼 |
struts.objectFactory.spring.autoWire | name | 和spring框架整合有關 |
struts.multipart.parser | jakarta | 指定文件上傳用的組件 |
struts.multipart.maxSize | 2097152 | 文件上傳總文件大小限制:2M |
struts.action.extension | action | 能進入Struts2框架內部的url地址後綴名。多個值用逗號分隔。 |
struts.enable.DynamicMethodInvocation | false | 是否允許動態方法調用 |
struts.devMode | false | 是否是開發模式。開發模式:改了配置文件,不需要重啓。輸出更多的錯誤信息。開發階段建議爲true。 |
struts.ui.theme | xhtml | 頁面展示用的主題 |
2、在struts.xml中覆蓋常量(即修改struts中default.properties定義的常量值)
3、依次類推,三個文件的配置如下圖所示:
十一、Struts2中配置文件元素的詳解
1、package元素:
package元素:作用是定義一個struts的包,它是把配置文件按照面向對象的思想來管理。分模塊開發。 即在struts2的配置文件中引入了面向對象思想,使用了分包管理。易於管理動作類。便於模塊化開發動作類。 name屬性:指定包的名稱。注意:包的名稱在配置文件中唯一。 extends屬性:指定當前包的父包。它是按照面向對象的思想管理的體現。 一般情況下需要繼承struts-default包,但不是必須的。不過如果不繼承的話,將無法使用struts2提供的核心功能。 struts-default.xml 中定義着 struts-default 這個包。而 struts-default.xml 是在我們的 struts.xml 加載之前加載。 abstract屬性:把包聲明爲一個抽象包。抽象包就是用來被繼承的。 只有沒有<action>元素的包,才能被定義爲抽象包。 namespace屬性:名稱空間。當指定了名稱空間之後,訪問路徑就變成了: 訪問路徑 = 名稱空間 + 動作名稱 當不指定該屬性時,該屬性有默認值,默認值是""。注意:不是"/"!!! 名稱空間的搜索順序: 第一步:先去找對應的名稱空間 在指定的名稱空間下找到了:就執行第二步。 在指定的名稱空間下沒找到:按照名稱空間結構向上追溯,一直到根名稱空間,只要在任何一級找到了,就執行第二步。 第二步:找動作名稱 先在指定的名稱空間下,搜索對應的動作名稱:找到了就執行動作類的動作方法。 在指定的名稱空間下沒找到對應的動作名稱:就前往默認的名稱空間下,找動作名稱。注意:它只找動作名稱。
package的namespace的執行順序,如下圖所示:
示例代碼:
<package name="p1" extends="struts-default" namespace="/user"> <!-- 名稱空間(namespace="/user") --> <!-- <action name="action1" class="com.itheima.web.action.Demo1Action" method="saveUser" > <result name="success">/success.jsp</result> </action> --> </package> <package name="p2" extends="struts-default"> <!-- 默認的名稱空間(namespace=""或者不寫該屬性) --> <action name="action2" class="com.itheima.web.action.Demo1Action" method="saveUser2" > <result name="success">/success.jsp</result> </action> </package> 訪問:http://localhost:8080/day25_04_struts2_package/user/action2.action,可以找得到,查找過程: 1、先查找名稱空間/user,有/user名稱空間; 2、再在該名稱空間查找動作名稱action2.action,沒有該動作名稱; 3、再去默認的名稱空間查找,有默認的名稱空間; 4、再在該名稱空間查找動作名稱action2.action,有該動作名稱,則執行該動作。
2、action元素:
action元素:是用於定義動作名稱,動作類和動作方法的映射,即配置動作用的。以及當出現不同情況時前往指定的結果視圖 。 name屬性:動作的名稱。和jsp頁面上的請求url中的名稱對應起來。注意在此處不能寫.action。 class屬性:指定動作類,即動作類全名。 method屬性:指定要執行的動作方法,即動作類中的方法名稱。默認是public String execute() { } 方法要求: 1. public的 2. 返回值必須是String 3. 沒有參數 可以修改默認動作類,注意:我們一般不改 <default-class-ref class="你自己的動作類" /> 默認的動作類是:com.opensymphony.xwork2.ActionSupport 是在struts-default.xml中定義的。
3、編寫動作類的三種方式:
a.方式一:動作類就是一個POJO(Plain Old Java Object: 原始的老的java對象),是非常簡單的JavaBean。示例代碼如下:
package com.itheima.web.action; /** * 創建動作類的第一種方式: * 創建一個普通的java類。 * 它就是一個POJO,是非常簡單的javabean。 * 原始的 老的 java 對象 * Plain Old Java Object * POJO類是指沒有實現任何接口以及除了Object類以外,沒有繼承任何父類。 * struts2通過獲取struts.xml獲取到完全的類名,然後底層通過反射,執行方法。 * 該創建動作類的方式的特點:一點也看不到有struts2的痕跡。 * * @author cmj */ public class Demo1Action { public String hello() { System.out.println("動作類執行了"); return "success"; } }
b.方式二:動作類實現com.opensymphony.xwork2.Action接口。示例代碼如下:
package com.itheima.web.action; import com.opensymphony.xwork2.Action; /** * 創建動作類的第二種方式: * 動作類實現com.opensymphony.xwork2.Action接口。 * 創建一個普通類,實現Action接口,實現接口中的方法。 * * Action接口中的常量: * 常量名 默認常量值 說明 * SUCCESS "success" 當動作執行成功後,前往指定的位置 * NONE "none" 不返回任何結果視圖,和 return null; 效果是一樣的 * ERROR "error" 當執行動作方法,出現異常後,前往指定的位置 * INPUT "input" 數據回顯 * LOGIN "login" 一般用於返回登錄頁面 * * @author cmj */ public class Demo2Action implements Action { public String execute() throws Exception { System.out.println("動作類執行了"); return null; } }
c.方式三:動作類繼承com.opensymphony.xwork2.ActionSupport類。推薦使用方式三。示例代碼如下:
package com.itheima.web.action; import com.opensymphony.xwork2.ActionSupport; /** * 創建動作類的第三種方式: * 創建一個動作類,繼承com.opensymphony.xwork2.ActionSupport類。推薦使用方式三。 * 意義:提供了一些基本的功能。比如驗證和國際化消息提示等。 * 我們在開發中採取這種方式,來創建我們的動作類。 * * @author cmj */ public class Demo3Action extends ActionSupport{ // 當我們在該類中什麼都不寫,一個動作方法都不提供時: // 有一個默認的動作方法:public String execute() throws Exception { return SUCCESS; } }
4、動作的調用:
a.使用通配符: 優先級:絕對匹配優先。使用通配符的按照在配置文件中的先後順序進行匹配的。 b.使用動態方法調用: 示例代碼如下: 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> <!-- 先設置爲開發者模式 --> <constant name="struts.devMode" value="true" /> <!-- 開啓動態方法調用 --> <constant name="struts.enable.DynamicMethodInvocation" value="true"/> <package name="p1" extends="struts-default"> <!-- 動作方法調用的配置 <action name="addUser" class="com.itheima.web.action.UserAction" method="addUser"> <result name="success">/addUser.jsp</result> </action> <action name="updateUser" class="com.itheima.web.action.UserAction" method="updateUser"> <result name="success">/updateUser.jsp</result> </action> <action name="deleteUser" class="com.itheima.web.action.UserAction" method="deleteUser"> <result name="success">/deleteUser.jsp</result> </action> <action name="findUser" class="com.itheima.web.action.UserAction" method="findUser"> <result name="success">/findUser.jsp</result> </action> --> <!-- 使用通配符,配置動作方法 *表示的是動作的名稱,當有和動作名稱相匹配的時候可以用{出現的位置}來代替 <action name="*_*" class="com.itheima.web.action.{2}Action" method="{1}{2}"> <result name="success">/{1}{2}.jsp</result> </action> --> <!-- 動態方法調用的配置 --> <action name="user" class="com.itheima.web.action.UserAction"> <result name="success">/success.jsp</result> </action> </package> </struts>
inex.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>title</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> </head> <body> <%-- 使用通配符,訪問動作類和動作方法 <a href="${pageContext.request.contextPath}/add_User.action" >添加用戶</a><br> <a href="${pageContext.request.contextPath}/update_User.action" >更新用戶</a><br> <a href="${pageContext.request.contextPath}/delete_User.action" >刪除用戶</a><br> <a href="${pageContext.request.contextPath}/find_User.action" >查詢用戶</a><br> --%> <%-- 使用動態方法調用,格式如下: 動作名稱!動作方法名稱.action 或者 動作名稱!動作方法名稱 --%> <a href="${pageContext.request.contextPath}/user!addUser.action" >添加用戶</a> <a href="${pageContext.request.contextPath}/user!updateUser.action" >更新用戶</a> <a href="${pageContext.request.contextPath}/user!deleteUser.action" >刪除用戶</a> <a href="${pageContext.request.contextPath}/user!findUser.action" >查詢用戶</a> </body> </html>
十二、Struts2中結果視圖詳解
1、resulst元素:
resulst元素:配置邏輯結果視圖,即爲動作指定結果視圖。 name屬性:結果視圖名稱。與動作方法的返回值對應,當一致時前往指定的jsp。 type屬性:結果視圖類型。不寫的時候,有默認值,默認值是dispatcher(請求轉發)。 常用取值: dispatcher:請求轉發 ,是默認值(本動作下) <result name="success" type="dispatcher">/success.jsp</result> redirect:請求重定向(本動作下) <result name="success" type="redirect">/success.jsp</result> chain:請求轉發到另一個動作 請求轉發到同包(同名稱空間)下的另一個動作 <result name="success" type="chain">action2</result> 請求轉發到不同包(不同名稱空間)下的另一個動作 <result name="success" type="chain"> <param name="namespace">/n2</param> <param name="actionName">action3</param> </result> 使用的是注入的思想,在執行之重定向之前,會先獲取這兩個參數的值 調用的就是setNamespace("/n2")和setActionName("action3") redirectAction:請求重定向到另一個動作 請求重定向到同包(同名稱空間)下的另一個動作 <result name="success" type="redirectAction">action2</result> 請求重定向不同包(不同名稱空間)下的另一個動作 <result name="success" type="redirectAction"> <param name="namespace">/n2</param> <param name="actionName">action3</param> </result> 使用的是注入的思想,在執行之重定向之前,會先獲取這兩個參數的值 調用的就是setNamespace("/n2")和setActionName("action3")
result元素中type的取值,type屬性的取值在 struts-default.xml 中定義,如下圖所示:
2、result元素中param子元素
在請求轉發或者請求重定向到不同包下的動作時,都用到了result元素的子元素param。 param元素的作用:依賴注入(Dependence Injection)思想: 我們通過struts-default.xml中的result-types元素中配置可以看出,每個結果類型視圖其實都是靠一個類來實現的。而param元素就是將配置的參數,注入到該類中。 調用的是對應類的setter方法進行注入的。例如:setNamespace("/n2")和setActionName("action3")
示例代碼如下:
<?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> <constant name="struts.devMode" value="true"/> <package name="p1" extends="struts-default"> <action name="action1" class="com.itheima.web.action.Demo1Action"> <result name="success" type="chain"> <!-- 轉發到不同包(不同名稱空間)下的另一個動作 --> <param name="namespace">/n2</param> <param name="actionName">action3</param> </result> </action> <!-- 沒有給定動作類,默認的動作類是:com.opensymphony.xwork2.ActionSupport,沒有給定動作方法,默認的動作方法是:execute --> <action name="action2"> <result name="success" > <param name="location">/success.jsp</param> </result> </action> </package> <package name="p2" extends="struts-default" namespace="/n2"> <action name="action3"> <result name="success" >/success.jsp</result> </action> </package> </struts>
3、自定義結果類型及其配置
通過前面的內容,我們看出,其實結果類型就是一個類: 這些類都實現了com.opensymphony.xwork2.Result接口。 或者繼承自該接口的實現類org.apache.struts2.dispatcher.StrutsResultSupport。 這些類都有一個doExecute方法,用於執行結果視圖。 綜上:我們也可以自己寫一個結果視圖。 例子: 輸出CAPTCHA圖像的結果類型。 CAPTCHA(Completely Automated Public Turing Test to Tell Computers and Humans Apart: 全自動區分計算機和人類的圖靈測試) ————>簡稱:驗證碼。 步驟: 1.編寫一個普通類,繼承自StrutsResultSupport的類,並且重寫doExcecute方法。此爲自定義結果類型的類。 2.在struts.xml中進行配置。 3.在配置action時,type屬性指定聲明的結果類型名稱。
1、編寫一個普通類,繼承自StrutsResultSupport
的類,並且重寫doExcecute
方法。此爲自定義結果類型的類。
package com.itheima.web.result; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.ServletActionContext; import org.apache.struts2.dispatcher.StrutsResultSupport; import cn.dsna.util.images.ValidateCode; import com.opensymphony.xwork2.ActionInvocation; /** * 自定義結果類型 * 第一步:編寫一個普通類,繼承自StrutsResultSupport的類,並且重寫doExcecute方法。 * 第二步:在struts.xml中進行配置。 * 第三步:在配置action時,type屬性指定聲明的結果類型名稱。 * * @author cmj */ public class CAPTCHAResult extends StrutsResultSupport { // 通過配置文件,調整生成圖片的大小 private int width; private int height; public int getWidth() { return width; } public void setWidth(int width) { this.width = width; } public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } /* * 使用第三方生成驗證碼的jar包 * 1.拷貝ValidateCode.jar到工程lib目錄 * 2.創建ValidateCode的對象 * 3.獲取響應對象輸出流 * 4.輸出到瀏覽器 */ // Servlet的中原來怎麼寫,現在還怎麼寫 @Override protected void doExecute(String finalLocation, ActionInvocation invocation) throws Exception { // 創建ValidateCode的對象,該對象的構造參數詳解:1:圖像寬度 2.圖像高度 3.數字的格式 4.干擾線條數 ValidateCode code = new ValidateCode(width, height, 4, 10); // 獲取響應對象輸出流 HttpServletResponse response = ServletActionContext.getResponse(); // 輸出到瀏覽器 code.write(response.getOutputStream()); } }
2、在struts.xml中進行配置,如下所示。 3、在配置action時,type屬性指定聲明的結果類型名稱。
<?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="p3" extends="myDefault"> <!-- 自定義結果類型 --> <result-types> <result-type name="captcha" class="com.itheima.web.result.CAPTCHAResult"></result-type> </result-types> <action name="captchaAction" class="com.itheima.web.action.CaptchaAction" > <result name="success" type="captcha"> <!-- 配置圖像的大小 --> <param name="width">240</param> <param name="height">40</param> </result> </action> </package> </struts>
4、建立動作類和動作方法
package com.itheima.web.action; import com.opensymphony.xwork2.ActionSupport; public class CaptchaAction extends ActionSupport { // 當我們在該動作類中什麼都不寫,即一個動作方法都不提供時: // 會有一個默認的動作方法:public String execute() throws Exception { return SUCCESS; } }
5、建立一個jsp頁面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>title</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <form action="" method="post"> 用戶名:<input type="text" name="username"/><br/> 密碼:<input type="password" name="password"/><br/> 驗證碼:<input type="text" name="valicateCode"/> <img src="${pageContext.request.contextPath}/captchaAction.action"/> <br/> <input type="submit" value="登錄" /> </form> </body> </html>
4、局部視圖和全局視圖
局部視圖的配置
全局視圖的配置
十三、Struts2中調用ServletAPI
獲取ServletAPI的兩種方式:
第一種方式:使用的是ServletActionContext
的對象(此種方式簡單明瞭,推薦此種方式)
第二種方式:使用的是依賴注入
的形式,把我們想要的對象注入進來,是由一個攔截器
爲我們做的。需要實現3個接口,實現其中的方法。
示例代碼如下:
package com.itheima.web.action; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.struts2.interceptor.ServletRequestAware; import org.apache.struts2.interceptor.ServletResponseAware; import org.apache.struts2.util.ServletContextAware; import com.opensymphony.xwork2.ActionSupport; /** * 獲取ServletAPI的兩種方式: * 第一種方式:使用的是 ServletActionContext 的對象(此種方式簡單,推薦此種方式) * 第二種方式:使用的是 依賴注入 的形式,把我們想要的對象注入進來,是由一個攔截器爲我們做的。需要實現3個接口,實現其中的方法。 * * @author cmj */ public class Demo1Action extends ActionSupport implements ServletRequestAware, ServletResponseAware, ServletContextAware { private HttpServletRequest request; private HttpServletResponse response; private ServletContext application; public String execute() { // 方式一:使用 ServletActionContext 對象 // HttpServletRequest request = ServletActionContext.getRequest(); // HttpServletResponse response = ServletActionContext.getResponse(); // ServletContext application = ServletActionContext.getServletContext(); // HttpSession session = request.getSession(); // System.out.println(request); // org.apache.struts2.dispatcher.StrutsRequestWrapper@500b3f4c // System.out.println(response); // org.apache.catalina.connector.ResponseFacade@1268bfa2 // System.out.println(application); // org.apache.catalina.core.ApplicationContextFacade@1afd2e1f // System.out.println(session); // org.apache.catalina.session.StandardSessionFacade@63df0310 // 方式二:使用依賴注入 HttpSession session = request.getSession(); System.out.println(request); System.out.println(response); System.out.println(application); System.out.println(session); return null; } @Override public void setServletContext(ServletContext application) { this.application = application; } @Override public void setServletResponse(HttpServletResponse response) { this.response = response; } @Override public void setServletRequest(HttpServletRequest request) { this.request = request; } }
十四、分文件編寫Struts2的配置文件
1、不分文件開發可能產生的問題 就類似於我們在寫java類時,所有代碼都寫在一個類裏,甚至寫在一個方法裏。
因爲當3個人都checkout了struts.xml文件時,第一個人更新提交了,後面的人在沒有更新時就提交,第一個人寫的可能就白寫了。如下圖所示:
2、分文件編寫Struts2的配置文件
我們現在常說的組件式開發
,如下圖所示:
分文件編寫Struts2的配置文件,如下圖所示: