1.1 攔截器的作用。
參考答案:
攔截器適合封裝一些共通處理,便於重複利用.例如請求參數給Action屬性,日誌的記錄,權限檢查, 事務處理等.攔截器是通過配置方式調用,因此使用方法比較靈活,便於維護和擴展。
1.2 fileUpload攔截器原理。
參考答案:
該攔截器首先會調用commons-file-upload.jar組件將客戶端上傳的文件保存到服務器臨時目錄下,之後將臨時目錄下的文件對象給Action屬性複製.當Action和Result調用完畢後,清除臨時目錄下的文件.因此在Action業務方法中,需要做文件複製,將臨時文件轉移到目標目錄中。
1.3 Struts2完整工作流程。
參考答案:
a.客戶發送一個Action請求,請求交給控制器
b.控制器創建一個ValueStack,將Action壓入棧頂
c.控制器調用ActionInvocation組件執行請求處理
d.ActionInvocation組件調用請求相關的攔截器組件--前部分處理.
e.然後再調用Action組件業務方法
f.然後再調用Result組件處理方法
g.最後執行攔截器組件--後部分處理.
h.將響應信息輸出,爲客戶端響應
2.1 閱讀下面的代碼,並在指定位置添加註釋。
- <struts>
- <package name="day05" extends="struts-default">
- <interceptors>
- <!—此行代碼的作用是( 註冊SomeInterceptor攔截器 )-->
- <interceptorname="someInterceptor"
- class="com.tarena.interceptor.SomeInterceptor" />
- </interceptors>
- <actionname="some"
- class="com.tarena.action.SomeAction">
- <!—此行代碼的作用是( 使用SomeInterceptor攔截器 )-->
- <interceptor-refname="someInterceptor"/>
- <result>/WEB-INF/jsp/ok.jsp</result>
- </action>
- </package>
- </struts>
<struts> <package name="day05" extends="struts-default"> <interceptors> <!—此行代碼的作用是( 註冊SomeInterceptor攔截器 )--> <interceptor name="someInterceptor" class="com.tarena.interceptor.SomeInterceptor" /> </interceptors> <action name="some" class="com.tarena.action.SomeAction"> <!—此行代碼的作用是( 使用SomeInterceptor攔截器 )--> <interceptor-ref name="someInterceptor"/> <result>/WEB-INF/jsp/ok.jsp</result> </action> </package> </struts>
3 編程題(改代碼,寫代碼)
3.1 NETCTOSS登錄檢查攔截器
在Day04“NETCTOSS資費更新”案例基礎上,添加登錄檢查攔截器功能。當用戶沒有登錄的時候,不能對資費信息進行修改和刪除。
參考答案:
1.按照Day02的“NETCTOSS資費的分頁顯示”案例中,拷貝工程的方法,拷貝struts04_3創建struts05_2工程。
2.經過拷貝創建好的工程,沒有登錄的內容,所以要把登錄的內容整合到struts05_2中。整合登錄時需要將Day04的“基於stream Result生成驗證碼”(struts04_1)案例的內容整合到struts05_2中,最終項目工程結構如圖-4,圖-5所示。
圖- 4
圖- 5
整合步驟如下:
a.拷貝struts04_1中ImageAction.java和LoginAction.java到struts05_2的
com.tarena.netctoss.action包下。
b.在struts05_2工程中創建BaseAction.java,放置目錄請參考圖-4,內容如下:
- import java.util.Map;
- import org.apache.struts2.interceptor.RequestAware;
- import org.apache.struts2.interceptor.SessionAware;
- public classBaseAction implements RequestAware,SessionAware{
- protected Map<String,Object>request;
- protected Map<String, Object>session;
- public void setSession(Map<String, Object>session) {
- this.session = session;
- }
- public void setRequest(Map<String, Object>request) {
- this.request = request;
- }
- }
import java.util.Map; import org.apache.struts2.interceptor.RequestAware; import org.apache.struts2.interceptor.SessionAware; public class BaseAction implements RequestAware,SessionAware{ protected Map<String,Object> request; protected Map<String, Object> session; public void setSession(Map<String, Object> session) { this.session = session; } public void setRequest(Map<String, Object> request) { this.request = request; } }
c. 拷貝struts04_1中AdminInfoDAO.java拷貝到struts05_2的com.tarena.netctoss.dao下;拷貝struts04_1中AdminInfo.java拷貝到struts05_2的com.tarena.netctoss.pojo下;拷貝struts04_1中ImageUtil.java拷貝到struts05_2的com.tarena.netctoss.util下。
d.修改struts05_2的struts.xml,添加如下關於登錄的配置:
- <package name="login" extends="struts-default">
- <!-- 登錄處理 -->
- <actionname="toLogin">
- <resultname="success">/WEB-INF/login.jsp</result>
- </action>
- <actionname="login" class="com.tarena.netctoss.action.LoginAction">
- <resultname="success">/WEB-INF/main.jsp</result>
- <resultname="login">/WEB-INF/login.jsp</result>
- </action>
- <actionname="image" class="com.tarena.netctoss.action.ImageAction">
- <resulttype="stream">
- <paramname="inputName">imageStream</param>
- </result>
- </action>
- </package>
<package name="login" extends="struts-default"> <!-- 登錄處理 --> <action name="toLogin"> <result name="success">/WEB-INF/login.jsp</result> </action> <action name="login" class="com.tarena.netctoss.action.LoginAction"> <result name="success">/WEB-INF/main.jsp</result> <result name="login">/WEB-INF/login.jsp</result> </action> <action name="image" class="com.tarena.netctoss.action.ImageAction"> <result type="stream"> <param name="inputName">imageStream</param> </result> </action> </package>
e. 拷貝struts04_1中的main.jsp和login.jsp到struts05_2的WEB-INF目錄下。修改login.jsp的form的action,如圖-6所示。
圖- 6
修改main.jsp的連接,如圖-7所示。
圖- 7
f.測試登錄功能是否成功;測試資費的列表顯示,修改,刪除是否成功(測試過程略)
3.創建LoginInterceptor.java攔截器,攔截器的作用是:從session去key爲“user”的value,如果取到的value是null,說明該用戶沒有登錄,返回到登錄頁面。
- public classLoginInterceptor extends AbstractInterceptor {
- @Override
- public Stringintercept(ActionInvocationinvocation) throws Exception {
- Map<String,Object>session = invocation.getInvocationContext().getSession();
- if(session.get("user") == null){
- //定位到登陸界面
- return "login";
- }
- return invocation.invoke();
- }
- }
public class LoginInterceptor extends AbstractInterceptor { @Override public String intercept(ActionInvocation invocation) throws Exception { Map<String,Object> session = invocation.getInvocationContext().getSession(); if(session.get("user") == null){ //定位到登陸界面 return "login"; } return invocation.invoke(); } }
4.修改struts.xml,註冊LoginInterceptor,並應用到資費的修改和刪除上。
- <?xmlversion="1.0" encoding="UTF-8"?>
- <!DOCTYPE struts PUBLIC
- "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"
- "http://struts.apache.org/dtds/struts-2.1.dtd">
- <struts>
- <package name="fee" extends="json-default" namespace="/fee">
- <interceptors>
- <interceptorname="checkLogin" class="com.tarena.netctoss.interceptor.LoginInterceptor"></interceptor>
- <interceptor-stackname="checkLoginStack">
- <interceptor-refname="checkLogin"/>
- <interceptor-refname="defaultStack"/>
- </interceptor-stack>
- </interceptors>
- <global-results>
- <resultname="login" type="redirectAction">
- <paramname="actionName">toLogin</param>
- <paramname="namespace">/</param>
- </result>
- </global-results>
- <!-- 資費處理 -->
- <actionname="feeList"
- class="com.tarena.netctoss.action.fee.FeeListAction">
- <paramname="pageSize">3</param>
- <resultname="success">/WEB-INF/fee/fee_list.jsp</result>
- </action>
- <actionname="feeDelete"
- class="com.tarena.netctoss.action.fee.FeeDeleteAction">
- <interceptor-refname="checkLoginStack"/>
- <resultname="success" type="redirectAction">feeList</result>
- </action>
- <actionname="toAdd">
- <result>/WEB-INF/fee/fee_add.jsp</result>
- </action>
- <actionname="validName"
- class="com.tarena.netctoss.action.fee.ValidNameAction">
- <resulttype="json">
- <paramname="root">ok</param>
- </result>
- </action>
- <actionname="fee_*" class="com.tarena.netctoss.action.fee.FeeUpdateAction" method="{1}">
- <interceptor-refname="checkLoginStack"/>
- <resultname="success">/WEB-INF/fee/fee_modi.jsp</result>
- </action>
- </package>
- <package name="login" extends="struts-default">
- <!-- 登錄處理 -->
- <actionname="toLogin">
- <resultname="success">/WEB-INF/login.jsp</result>
- </action>
- <actionname="login"
- class="com.tarena.netctoss.action.LoginAction">
- <resultname="success">/WEB-INF/main.jsp</result>
- <resultname="login">/WEB-INF/login.jsp</result>
- </action>
- <actionname="image"
- class="com.tarena.netctoss.action.ImageAction">
- <resulttype="stream">
- <paramname="inputName">imageStream</param>
- </result>
- </action>
- </package>
- </struts>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd"> <struts> <package name="fee" extends="json-default" namespace="/fee"> <interceptors> <interceptor name="checkLogin" class="com.tarena.netctoss.interceptor.LoginInterceptor"></interceptor> <interceptor-stack name="checkLoginStack"> <interceptor-ref name="checkLogin"/> <interceptor-ref name="defaultStack"/> </interceptor-stack> </interceptors> <global-results> <result name="login" type="redirectAction"> <param name="actionName">toLogin</param> <param name="namespace">/</param> </result> </global-results> <!-- 資費處理 --> <action name="feeList" class="com.tarena.netctoss.action.fee.FeeListAction"> <param name="pageSize">3</param> <result name="success">/WEB-INF/fee/fee_list.jsp</result> </action> <action name="feeDelete" class="com.tarena.netctoss.action.fee.FeeDeleteAction"> <interceptor-ref name="checkLoginStack"/> <result name="success" type="redirectAction">feeList</result> </action> <action name="toAdd"> <result>/WEB-INF/fee/fee_add.jsp</result> </action> <action name="validName" class="com.tarena.netctoss.action.fee.ValidNameAction"> <result type="json"> <param name="root">ok</param> </result> </action> <action name="fee_*" class="com.tarena.netctoss.action.fee.FeeUpdateAction" method="{1}"> <interceptor-ref name="checkLoginStack"/> <result name="success">/WEB-INF/fee/fee_modi.jsp</result> </action> </package> <package name="login" extends="struts-default"> <!-- 登錄處理 --> <action name="toLogin"> <result name="success">/WEB-INF/login.jsp</result> </action> <action name="login" class="com.tarena.netctoss.action.LoginAction"> <result name="success">/WEB-INF/main.jsp</result> <result name="login">/WEB-INF/login.jsp</result> </action> <action name="image" class="com.tarena.netctoss.action.ImageAction"> <result type="stream"> <param name="inputName">imageStream</param> </result> </action> </package> </struts>
5. 測試,訪問http://localhost:8080/struts05_2/fee/feeList.action,如圖-8所示。
圖- 8
點擊“修改”,返回到登錄頁面,如圖-9所示。
圖- 9
輸入正確的用戶名和密碼,點擊登錄,進入main.jsp,如圖-10所示。
圖- 10
點擊資費管理進入列表頁,再次點擊修改,進入修改頁面,如圖-11所示。
圖- 11
刪除的攔截過程和修改類似,請學員自己測試。