Struts2基礎-1- 簡單java類實現Action控制器
Strut2中,Action可以不繼承任何特殊的類或不實現任何特殊的接口,可以只編寫一個普通的Java類作為Action類,只要該類含有一個返回字符串的無參的public方法即可!實際開發中,通常繼承ActionSupport類(該類繼承了Action接口)來編寫Action請求處理類。以下就以普通Java類作為Actoin類進行示例:
項目結構
1。web.xml配置
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" 3xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 5 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 6 <welcome-file-list> 7 <welcome-file>index.jsp</welcome-file> 8 </welcome-file-list> 9 10 <filter> 11<filter-name>StrutsPrepareAndExecuteFilter</filter-name> 12 <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> 13 </filter> 14 15 <filter-mapping> 16 <filter-name>StrutsPrepareAndExecuteFilter</filter-name> 17<url-pattern>/*</url-pattern> //對所有請求進行攔截
<!--<url-pattern>*.action</url-pattern>--> //對以.action結尾的請求進行攔截
18 </filter-mapping> 19 20 </web-app>
2. Action類
1 package cn.test.action; 2 3 public class UserAction { 4 5 public String login(){ 6 return "success"; 7 } 8 9 public String register(){ 10 return "success"; 11 } 12 13 }
3.struts.xml配置Action類
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE struts PUBLIC 3 "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" 4 "http://struts.apache.org/dtds/struts-2.3.dtd"> 5 <struts> 6 <package name="user" namespace="/user" extends="struts-default"> 7 <action name="login" class="cn.test.action.UserAction" method="login"> 8 <result>/login.jsp</result><!-- result不寫name屬性,默認就是success --> 9 </action> 10 <action name="register" class="cn.test.action.UserAction" method="register"> 11 <result>/register.jsp</result> 12 </action> 13 </package> 14 15 </struts>
4. jsp頁面,沒有實質性代碼,僅僅作為展示Struts2請求處理展示
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 %> 6 7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 8 <html> 9 <head> 10 <base href="<%=basePath%>"> 11 <title>My JSP ‘login.jsp‘ starting page</title> 12 </head> 13 14 <body> 15 This is my login JSP page. <br> 16 </body> 17 </html>
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 %> 6 7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 8 <html> 9 <head> 10 <base href="<%=basePath%>"> 11 <title>My JSP ‘register‘ starting page</title> 12 </head> 13 14 <body> 15 This is my register JSP page. <br> 16 </body> 17 </html>
5.部署並訪問:
http://localhost:8080/strutsstu0/user/login 結果如下:
訪問http://localhost:8080/strutsstu0/user/register 結果如下
如果web.xml中 url-pattern 配置成 <url-pattern>*.action</url-pattern> ,那麽訪問時就要 在後面加上.action了 :http://localhost:8080/strutsstu0/user/login.action,結果如下:
6. Struts2執行過程分析:
(1)web.xml
Struts2框架基於MVC模式,基於MVC模式框架的核心就是控制器對所有請求進行統一處理。Struts2的控制器 StrutsPrepareAndExecuteFilter 由Servlet API中的Filter充當,
當Web容器接收到請求後,將請求交給Web.xml中配置的過濾器StrutsPrepareAndExecuteFilter ,這個過濾器對框架進行初始化,以及處理所有的請求。(任何一個web應用程序都是基於請求/響應模式進行構建的,無論采用哪種MVC框架,都離不開Web.xml文件的配置。只有在web應用中配置了web.xml文件,MVC框架才能真正地與web應用融合起來。)
StrutsPrepareAndExecuteFilter 可以包含一些初始化參數,如果沒有配置初始化參數,Struts2框架默認加載Struts-default.xml、struts-plugin.xml 和 struts.xml
(2) Action
Struts2框架中國年,控制器由兩個部分組成:核心控制器Filter 用於攔截用戶請求,對請求進行處理;業務控制器,調用相應的Model類實現業務處理,返回結果
struts.xml配置文件中,將一個請求的URI對應到一個Action類,當一個請求匹配某個Action的名稱時,框架就會使用這個Action類處理請求。
<package name="user" namespace="/user" extends="struts-default"> 7 <action name="login" class="cn.test.action.UserAction" method="login"> 8 <result>/login.jsp</result><!-- result不寫name屬性,默認就是success --> 9 </action> 10 <action name="register" class="cn.test.action.UserAction" method="register"> 11 <result>/register.jsp</result> 12 </action> 13 </package>
配置講解:
Struts2框架會把action result等組織在一個名為package 的邏輯單元中,從而簡化維護工作,提高重用性,每一個包都包含了將要用到的action result等的定義。Struts2中的包可以“繼承”
已經定義好的包,從而繼承原有包的所有定義(包括action result 等的配置)並且可以添加自己包的位置。
struts.xml中使用 package元素定義包,其中:
name屬性為必須,並且唯一的,用來指定包的名稱(被其他包引用)
extends屬性指定要擴展的包,一般默認繼承 Struts-default 包(這個包由struts2框架愛定義,其中配置了大量常用的Struts2的特性。如果沒有這些特性,則簡單的在action中獲取請求數據都無法完成。)
namespace屬性可選,該屬性定義該包中action的命名空間,如果沒有設置該屬性,action被放入默認命名空間中,Struts2框架使用action的名稱和它所在的包的命名空間來標識一個action,默認的命名空間用" "來表示,也可以使用“ / ”來定義一個根命名空間,兩者有區別。當Struts2接收到一個請求時,框架會講URL分為namespace 和action 名稱兩部分,框架首先在namespace 命名空間中查找這個action,若沒有找到,則再在默認命名空間中查找。
例如,請求URL為/mysapce/somespace/some.action ,框架首先會在/mysapce/somespace命名空間下查找some.action ,如果沒有找到,框架會到默認的命名空間中去查找
示例:在上述項目的 struts.xml配置文件中增加 默認命名空間,action元素的name屬性仍然叫login,修改跳轉頁面為index.jsp
1 <!-- 默認命名空間 --> 2 <package name="" namespace="/" extends="struts-default"> 3 <action name="login" class="cn.test.action.UserAction" method="login"> 4 <result>/index.jsp</result> 5 </action> 6 </package>
添加index.jsp頁面
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 %> 6 7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 8 <html> 9 <head> 10 <base href="<%=basePath%>"> 11 <title>My JSP ‘register‘ starting page</title> 12 </head> 13 14 <body> 15 This is my index JSP page. <br> 16 </body> 17 </html>
然後重新部署並訪問http://localhost:8080/strutsstu0/login ,結果如下,也就是說,此時處理請求的是默認的根命名空間下的action,頁面跳轉到了index.jsp
(3)Result
Action類在處理完用戶請求後,會返回一個處理結果,這個結果是一個簡單字符串,框架根據這個字符串選擇對應的result,因此又將這個字符串成為邏輯視圖名稱,這個邏輯視圖名稱由result元素的name屬性來表示,result元素的值(<result> </result> 中的內容)用來指定這個邏輯視圖對應的物理視圖資源的位置,需要註意的是,邏輯視圖名稱只有與物理視圖資源聯系在以一起才能發揮作用,所以必須配置二者之間的對應關系。
result元素的配置由兩部分組成,一部分是Result所代表的實際資源的位置以及result名稱,另一部分是result的類型,由result元素的type屬性設定
result元素的name屬性不寫,則默認是“success”, type屬性不寫,則默認是"dispatcher",<result >/index.jsp</result> 等價於
<result name="success" type="dispatcher">/index.jsp</result>
總結:struts2應用的這個過程都是按照請求/響應的過程執行的,如下圖所示:
整體就三個步驟:
(1)當web容器接收到請求之後,將請求交給web.xml中配置的struts2框架的核心控制器StrutsPrepareAndExecuteFilter
(2)由StrutsPrepareAndExecuteFilter 確定請求對應的Action(業務控制器)
(3)框架根據Action返回的結果字符串,由核心控制器StrutsPrepareAndExecuteFilter 選擇對應的result ,將結果呈現給用戶
註意:
(a)Action作為業務控制器,只負責返回結果,而不與視圖相關聯,這樣做的優勢在於,當視圖發生變化時,無需修改Action類的代碼,僅需修改配置文件即可
(b)當 StrutsPrepareAndExecuteFilter 調用相應的視圖時,默認采用轉發的形式(forword)跳轉到指定的JSP頁面
<result name="success" type="dispatcher">/index.jsp</result>
type值可以是:
(1)dispatcher:
默認的結果類型,Struts2內部使用功能Servlet API的RequestDispathcer來轉發請求到指定的視圖資源,請求中國年包含的請求數據仍然存在
(2)redirect:
請求重定向,就是服務器告訴請求說,你自己去重新請求指定的視圖資源吧。redirect結果類型在內部使用的HttpServletResponse對象的sengRedirect()方法將請求重定向到指定的URL,這意味著請求中包含的參數,屬性,action實例以及action封裝的屬性都將全部丟失
(3)redirectAction:
將重定向到另外一個Action。是使用HttpServletResponse對象的sengRedirect()方法將請求重定向到另外一個action.也就是說,當請求處理完成後,需要在另一個Action中繼續處理請求時,可以使用redirectAction重定向到指定Action(由於是重定向,請求參數也會丟失)
7.struts配置文件加載路徑
以本機tomcat部署為例:可以看到部署路徑如下:
進入strutsstu0\WEB-INF\classes目錄下,可以看到struts.xml配置文件,Struts2允許將一個配置文件拆分成多個配置文件,但默認只加載 WEB-INF\classes目錄下的struts.xml文件
被拆分的配置文件需要在struts.xml中引入,例如: <include file ="struts-user.xml">
Struts2基礎-1- 簡單java類實現Action控制器