您好,登錄后才能下訂單哦!
在學(xué)習(xí)struts的時候,我們一定要掌握struts2的工作原理。只有當(dāng)我們明確了在struts2框架的內(nèi)部架構(gòu)的實現(xiàn)過程,在配置整個struts 的框架時,可以很好的進行邏輯上的配置。接下來我就先簡單的講解下struts2的框架工作原理:
一、struts2的工作原理
1、客戶端初始化一個指向Servlet容器(例如Tomcat)的請求;
2、這個請求經(jīng)過一系列的過濾器(Filter)(這些過濾器中有一個叫做ActionContextCleanUp的可選過濾器,這個過濾器對于Struts2和其他框架的集成很有幫助,例如:SiteMesh Plugin);
3、接著FilterDispatcher被調(diào)用,F(xiàn)ilterDispatcher詢問ActionMapper來決定這個請求是否需要調(diào)用某個Action;
4、如果ActionMapper決定需要調(diào)用某個Action,F(xiàn)ilterDispatcher把請求的處理交給ActionProxy;
5、ActionProxy通過ConfigurationManager詢問框架的配置文件,找到需要調(diào)用的Action類;
6、ActionProxy創(chuàng)建一個ActionInvocation的實例。
7、ActionInvocation實例使用命名模式來調(diào)用,在調(diào)用Action的過程前后,涉及到相關(guān)攔截器(Intercepter)的調(diào)用。
8、一旦Action執(zhí)行完畢,ActionInvocation負責(zé)根據(jù)struts.xml中的配置找到對應(yīng)的返回結(jié)果。返回結(jié)果通常是(但不總是,也可能是另外的一個Action鏈)一個需要被表示的JSP或者FreeMarker的模版。在表示的過程中可以使用Struts2框架中繼承的標簽。在這個過程中需要涉及到ActionMapper。
二、部署一個struts2項目的一般步驟
1)在Myeclipse中創(chuàng)建一個web項目,并將struts2需要的jar包導(dǎo)入進項目中,如下圖
2)在項目中的web.xml中進行配置struts2的框架,在web.xml中需要包含在<filter></filter>,在該節(jié)點下可以包含<filter-name>和<filter-mapin
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <display-name></display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <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>*.action</url-pattern> </filter-mapping> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>*.jsp</url-pattern> </filter-mapping> </web-app>
3)編寫Action類
4)創(chuàng)建好了Action類中要對action進行配置struts.xml,注意該配置文件的位置要在src的根目錄下
5)創(chuàng)建jsp的文件,進行測試
三、struts.xml的配置初探
先來看看struts的基本配置的大概情況
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN" "http://struts.apache.org/dtds/struts-2.1.7.dtd"> <struts> <package name="user" namespace="/" extends="struts-default"> <action name="*user" class="com.zzjmay.action.VaildateAction" method="{1}"> <result name="success">/success.jsp</result> <result name="input">/{1}.jsp</result> </action> </package> </struts>
從上面的代碼中可以看出,xml中包含的再根節(jié)點下<struts></struts>下。在實際項目中的編寫時,頭部信息需要更改,那么我們給以在導(dǎo)入的jar中的jar包中進行獲取
在struts-core-2.2.1.1.jar包下的struts2.0.dtd中進行獲取。
四、struts.xml中的package的配置
看著前面的代碼可以很清晰的看到package的屬性
屬性有:
1. name:邏輯上的包名
2. namespace:命名空間,用來區(qū)分同意struts下的相同action(注意是一種邏輯上的的路徑)
3. extends: 繼承某個配置文件
4. abstract
具體使用過程中要注意,有與命名空間的命名,我們要在相應(yīng)的過程中加上對應(yīng)的命名空間的路徑,例如:
<s:form action="db/login.action" method="post">
此代碼說明的就是將會去調(diào)用db命名空間下的login對應(yīng)的action
還需要注意的是:
<result>標簽的下的是物理路徑(絕對路徑),即指在項目中的實際位置,代碼如下
<result name="success">/login/error.jsp</result>
六、struts.xml中的result的配置
對于action的配置我這里面只是簡單的概括,具體很多細節(jié)性的東西我將專門寫一篇博客,主要講解的動態(tài)的對action進行配置
屬性有:
1. name:Action類的映射名稱
2. class:Action類的完整路徑
3. method:默認使用的execute()方法,如果要自定義觸發(fā)方法,需要使用method自定義
七、struts.xml配置過程中的注意信息
在實際開發(fā)的項目中,我們可能需要配置很多的action,有時候為了便于我們的分類,我們一般需要創(chuàng)建不同包下的struts-user.xml文件,不過最終我們的這些配置都是要導(dǎo)入進我們的struts.xml文件中。使用的標簽和jsp編程中<include>
struts.xml
[<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN" "http://struts.apache.org/dtds/struts-2.1.7.dtd"> <struts> <include file="struts-user.xml"></include> </struts>
struts-user.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN" "http://struts.apache.org/dtds/struts-2.1.7.dtd"> <struts> <constant name="struts.ui.theme" value="simple"></constant> <package name="user" namespace="/ss" extends="struts-default"> <action name="login" class="com.zzjmay.action.UserAction" method="execude2"> <!--result下的路徑是物理路徑 --> <result name="success">/login/success.jsp</result> <result name="error">/login/error.jsp</result> </action> </package> <!-- 包名不能相同 --> <package name="user123" namespace="/db" extends="struts-default"> <action name="login" class="com.zzjmay.action.UserAction" method="execude2"> <!--result下的路徑是物理路徑 --> <result name="success">/login/error.jsp</result> <result name="error">/login/success.jsp</result> </action> </package> </struts>
一、Action的創(chuàng)建方法
1)實現(xiàn)Action接口
2)繼承ActionSupport類,覆寫其中的方法
3)不繼承任何類都可以實現(xiàn),關(guān)鍵是在struts.xml中進行配置
二、Action動態(tài)方法的調(diào)用
在實際的項目中,一個action類的中,可能存在多個方法,而不同的方法執(zhí)行的效果是不一樣的,如果按照了一般性的配置,將無形的增加了程序員的負擔(dān)
第一種方法:在struts.xml中的action屬性標簽中用method屬性指定方法名(不怎么推薦使用)
第二種方法: jsp頁面中指定你要調(diào)用的那個方法
<form action=”login!myfun.action”,method=”post”>
在客戶端請求中進行動態(tài)的配置:映射名!方法名.action
這樣可以動態(tài)的調(diào)用action中的myfun方法,就不要在action標簽中進行method的配置
第三種方法:使用通配符進行配置(推薦使用:適用情況當(dāng)一個類中存在較多的響應(yīng)方法)
在配置<action> 時,可以在 name,class,method 中使用通配符,這是 另外一種形式的動態(tài)方法調(diào)用
<action name="*user" class="com.zzjmay.action.UserAction" method="{1}"> //這種通配是針對的是同一個action中,響應(yīng)不同的方法 在jsp頁面中調(diào)用的時候 <form action="loginuser.action" method="post"> <!-- 需要注意的是要保證表單中的name的命名要和Action中屬性的命名保持一致 --> 用戶名:<input type="text" name="username" id="username"><br> 密 碼:<input type="password" name="password" id="password"> <br> <input type="submit" value="提交"> </form>
注意:通過使用通配符的時候相當(dāng)于占位操作,其中的{1}表示第一個通配符,就上面的例子來講,當(dāng)jsp頁面中是loginuser.action進行調(diào)用的時候,實際上出發(fā)的Action類中的login()方法
通過通配符實現(xiàn),不同的類響應(yīng)不同的類中的方法:
<action name=“*_*" class="action.{1}Action" method="{2}"> <result >/{2}.jsp</result> </action>
三、 Action的動態(tài)結(jié)果的配置
含義:在實際運行當(dāng)中,Action類的處理業(yè)務(wù)的過程中,可能由于業(yè)務(wù)條件的復(fù)雜,會跳轉(zhuǎn)到不同頁面,那么為了節(jié)省result的配置,我們一般會采用動態(tài)結(jié)果的配置。其實很像我們在servlet中進行全局的forward的配置。
UserAction.Java
public class UserAction extends ActionSupport { private String nextResult; ... }
Struts2.xml
<action name="user" class="action.UserAction"> <result>/{nextResult}</result> </action>
四、接收用戶數(shù)據(jù)(推薦使用的實現(xiàn)ModelDriven的接口)
在這篇博客中我只是介紹常用的,并且在實際項目中效率較高的方法。我之所以推薦ModelDriven接口的方法,原因就是可以很好的分離顯示界面和業(yè)務(wù)邏輯的分離(解耦性)。
實現(xiàn)ModelDriven接口
步驟:
u 實現(xiàn)用戶登錄功能
u 創(chuàng)建User.java類
Ø 聲明用戶登錄信息
Ø 創(chuàng)建無參構(gòu)造
u 創(chuàng)建Action類
Ø 實現(xiàn)com.opensymphony.xwork2.ModelDriven接口
Ø 聲明User類對象并實例化
Ø 實現(xiàn)getModel ()方法,返回User類對象
u 創(chuàng)建JSP頁面
Ø 表單元素使用”屬性”設(shè)置name屬性
注意:
1) 首先,action要實現(xiàn)ModelDriven的接口,默認實現(xiàn)getModel()方法
2) 要在action中自己來實例化user的對象,而不像前面一種方法是有struts2的框架實現(xiàn)的
3) 比較突出的就是在jsp頁面中,表單元素的name屬性,直接用名字就可以來
UserAction.java
public class UserAction implements ModelDriven<User> { //要實例化 private User user=new User(); public User getUser() { return user; } public void setUser(User user) { this.user = user; } public String myfun() throws Exception { System.out.println("username="+user.getUsername()); System.out.println("password="+user.getPassword()); System.out.println("myfun....."); //用來進行處理 if(user.getUsername().equals(user.getPassword())){ return "success"; }else{ return "error"; } } public User getModel() { // TODO Auto-generated method stub return user; } }
login.jsp
<form action="loginuser.action" method="post"> <!-- 需要注意的是要保證表單中的name的命名要和Action中屬性的命名保持一致 --> 用戶名:<input type="text" name="username" id="username"><br> 密 碼:<input type="password" name="password" id="password"> <br> <input type="submit" value="提交"> </form>
五、在Action中訪問Servlet API
訪問Servlet API的實際項目中有兩種的方法訪問Servlet API
1)解耦的方法(實現(xiàn)三大接口程序RequestAware,ApplicationAware,SessionAware)
public class UserAction2 implements ModelDriven<User> ,RequestAware,SessionAware,ApplicationAware{ private User user = new User(); private Map<String, Object> requestMap; private Map<String, Object> sessionMap; private Map<String, Object> applicationMap; public void setApplication(Map<String, Object> applicationMap) { this.applicationMap=applicationMap; } public void setSession(Map<String, Object> sessionMap) { this.sessionMap=sessionMap; } public void setRequest(Map<String, Object> requestMap) { this.requestMap=requestMap; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } public String myfun() throws Exception { System.out.println("username=" + user.getUsername()); System.out.println("password=" + user.getPassword()); System.out.println("myfun2....."); // 用來進行處理 if (user.getUsername().equals(user.getPassword())) { sessionMap.put("Succ", "成功的哇2!?。?); Bookbiz bookbiz=new Bookbiz(); applicationMap.put("books",bookbiz.getBooks()); return "success"; } else { requestMap.put("errorMsg", "登陸失敗了2"); return "error"; } } public User getModel() { // TODO Auto-generated method stub return user; }
注意:在非解耦的方式中,struts2框架已經(jīng)將對應(yīng)的四大應(yīng)用作用域給封裝到了Map集合中,所以這里一開始定義的三個Map集合中可以相當(dāng)于操作四大作用域?qū)ο?/p>
2)非解耦的方法(實現(xiàn)兩大接口程序ServletReuqestAware,ServletContextAware):非解耦的意思就是說直接操作的Servlet API對象
public class UserAction4 implements ModelDriven<User>,ServletRequestAware,ServletContextAware{ private User user = new User(); private HttpServletRequest request; private HttpSession session; private ServletContext application; public void setServletContext(ServletContext application) { this.application = application; } public void setServletRequest(HttpServletRequest request) { this.request = request; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } ………………
注意:在實現(xiàn)接口中只實現(xiàn)了request和application的獲取
在實際項目開發(fā)當(dāng)中,需要的獲取session的方法是通過Httpsession session= request.getsession();
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。