4.1 Struts2架構
一、ActionMapper:
提供請求和Action之間的映射。根據請求查找是否存在對於的action,若有,翻譯描述action映射的ActionMapping對象,沒有,返回null
二、ActionMapping:
保存了調用action的映射信息,其中必須保存Action的命名空間信息和name屬性
三、ActionProxy:
在XWork和真正的Action之間充當代理
四、ActionInvocation:
表示執行狀態,它按順序保存攔截器,Action,實例,由ActionProxy建立,經過調用invoke()方法開始Action的執行
五、Interceptor(攔截器):
是一種能夠在請求處理以前或者以後執行的Struts2組件
4.2 Struts2攔截器
工做原理:
作一些Action執行前的預處理,能夠準備,過濾,改變或者操做任何能夠訪問的數據,包括Action
調用ActionInvocation的invoke()方法將控制轉交給後續的攔截器或者返回結果字符串終止執行,若是請求不該該繼續,能夠不調用invoke()方法
而是直接返回一個控制字符串,經過這種方式,能夠中止後續的執行,而且決定哪一個結果來呈現給客戶端。
作一些Action執行以後的處理:此時攔截器依然能夠改變能夠訪問的對象和數據,執行此時框架已經選擇一個結果呈現給客戶端了
攔截器的配置
一、經過<interceptor.../>元素來定義攔截器
二、經過<interceptor-ref.../>元素來使用攔截器
例:
<package name="default" extends="struts-default" namespace="/">
<interceptors>
定義攔截器
<interceptor name="interceptorName" class="interceptor.MyTimerInterceptor"/>
定義攔截器棧
<interceptor-stack name="interceptorStackName">
指定引用的攔截器
<interceptor-ref name="interceptorName | interceptorStackName"/>
</interceptor-stack>
</interceptors>
定義默認的攔截器引用
<default-interceptor-ref name="interceptorName | interceptorStackName"/>
<action name="actionName" class="interceptor.MyTimerAction">
爲Action指定攔截器引用
<interceptor-ref name="interceptorName | interceptorStackName"/>
<result name="success">indexWelcom.jsp</result>
<result name="input">index.jsp</result>
</action>
</package>
內置攔截器
一、params攔截器:將請求中的數據設置到Action的屬性上
二、staticParams攔截器:將在配置文件中經過action元素的子元素Param設置的參數設置到對應的Action屬性中
三、servletConfig攔截器:提供了一種將源於Servlet API 的各類對象注入Action中的方法
獲取ServletAPI對象的接口
接口 做用
ServletContextAware 設置ServletContext
ServletRequestAware 設置HttpServletRequest
ServletResponseAware 設置HttpServletResponse
ParameterAware 設置Map類型的請求參數
ResquestAware 設置Map類型的請求HttpServletRequest屬性
SessionAware 設置Map類型的會話HttpSession屬性
ApplicationAware 設置Map類型的應用程序做用域對象ServletContext
四、fileUpload攔截器:將文件和元數據從多重請求(multipart/form-data)轉換爲常規請求數據,以便於將他們設置在對於的Action上
五、validation攔截器:執行數據校驗
六、workflow攔截器:提供當數據校驗錯誤時終止執行流程的功能
七、exception攔截器:捕獲異常
攔截器棧
<interceptor-stack name="defaultStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="alias"/>
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="prepare"/>
<interceptor-ref name="il8n"/>
<interceptor-ref name="chain"/>
<interceptor-ref name="debugging"/>
<interceptor-ref name="profiling"/>
<interceptor-ref name="scopedModelDriven"/>
<interceptor-ref name="modelDriven"/>
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="staticParams"/>
<interceptor-ref name="params">
<param name="excludeParams">dojo\..*</param>
</interceptor-ref>
<interceptor-ref name="conversionError"/>
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="workflow">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
</interceptor-stack>
自定義攔截器
在Struts2中全部攔截器都直接或間接的實現接口om.opensymphony.xwork2.interceptor.Interceptor.
該接口提供了3各個方法:
void init():該攔截器初始化以後,在攔截器執行攔截以前,系統回調該方法,此方法只執行一次
void destroy():在攔截器實例被銷燬以前,系統回調該方法
String intercept(ActionInvocation invocation) throws Exception:是用戶須要實現的攔截動做,返回結果字符串
首先編寫權限驗證攔截器
html
public class AuthorizationInterceptor extends AbstractInterceptor { /** * 攔截器的攔截方法 */ @Override public String intercept(ActionInvocation invocation) throws Exception { //獲取回話信息 @SuppressWarnings("rawtypes") Map session=invocation.getInvocationContext().getSession(); users user=(users) session.get("login"); if(user==null){ //終止執行,返回登陸頁面 return Action.LOGIN; }else{ //繼續執行剩餘的Action和攔截器 return invocation.invoke(); } } }
而後在配置文件中定義攔截器並引用
java
<package name="default" extends="struts-default" namespace="/"> <interceptors> <!-- 定義權限驗證攔截器 --> <interceptor name="myAuthorization" class="interceptor.AuthorizationInterceptor"></interceptor> <interceptor-stack name="myStack"> <interceptor-ref name="defaultStack"/> <interceptor-ref name="myAuthorization"/> </interceptor-stack> </interceptors> <!-- 定義默認攔截器 --> <default-interceptor-ref name="myStack"/> <default-action-ref name="defaultAction"/> <!-- 定義全局結果 --> <global-results> <result name="login" type="redirect">login.jsp</result> </global-results> <action name="defaultAction" class="interceptor.MyTimerAction"> <result name="fail">fail.jsp</result> </action> <action name="house" class="interceptor.MyTimerAction"> <result name="success">guanli.jsp</result> <interceptor-ref name="myStack"></interceptor-ref> </action> </package>
4.3 實現文件上傳
UploadAction.java
瀏覽器
public class uploadAction extends ActionSupport{ //封裝上傳文件屬性 private File upload; //封裝上傳文件類型 private String uploadContentType; //封裝上傳文件名稱 private String uploadFileName; //封裝上傳文件的路徑 private String savePath; @Override public String execute()throws Exception{ byte[] buffer=new byte[1024]; //讀取文件 FileInputStream fis=new FileInputStream(getUpload()); //保存文件,設置保存目錄路徑 FileOutputStream fos=new FileOutputStream(getSavePath()+"\\"+this.getUploadFileName()); int length=fis.read(buffer); while(length>0) { //每次寫入length長度的內容 fos.write(buffer, 0, length); length=fis.read(buffer); } fis.close(); fos.flush(); fos.close(); return "success"; } //獲取上傳文件的保存路徑 //經過讀取存放目錄得到保存路徑 //省略get/set方法 public String getSavePath() { return ServletActionContext.getServletContext().getRealPath(savePath); } }
配置文件中定義uploadAction
session
<action name="download" class="interceptor.FileDownAction">
<param name="savePath">/upload</param>
<result name="success" type="stream">
<param name="contentType">application/octet-stream</param>
<param name="inputName">inputStream</param>
<param name="contentDisposition">attachment;filename="${fileName}"</param>
<param name="bufferSize">4096</param>
</result>
</action>
多文件上傳
架構
public class uploadActions extends ActionSupport{ //封裝上傳文件屬性 private File[] upload; //封裝上傳文件類型 private String[] uploadContentType; //封裝上傳文件名稱 private String[] uploadFileName; //封裝上傳文件的路徑 private String savePath;
//省略get/set方法 @Override public String execute()throws Exception{ byte[] buffer=new byte[1024]; for (int i = 0; i < upload.length; i++) { //讀取文件 FileInputStream fis=new FileInputStream(getUpload()[i]); //保存文件,設置保存目錄路徑 FileOutputStream fos=new FileOutputStream(getSavePath()+"\\"+this.getUploadFileName()); int length=fis.read(buffer); while(length>0) { //每次寫入length長度的內容 fos.write(buffer, 0, length); length=fis.read(buffer); } fis.close(); fos.flush(); fos.close(); } return "success"; } }
4.4文件下載
Stream結果類型
contentType 設置發送到瀏覽器的MIME類型
contentLength 設置文件大小
contentDisposition 設置響應的HTTP頭信息中的content-Disposition參數的值
inputName 指定Action中提供的inputStream類型的屬性名稱
bufferSize 設置讀取和下載文件是的緩衝區大小
FileDownAction.java
app
public class FileDownAction extends ActionSupport { //讀取下載文件目錄 private String inputPath; //下載文件的文件名 private String fileName; //讀取下載文件的輸入流 private InputStream inputStream; //下載文件類型 private String contentType; public String getInputPath() { return inputPath; } public void setInputPath(String inputPath) { this.inputPath = inputPath; } public String getFileName() { return fileName; } public void setFileName(String fileName) { this.fileName = fileName; } public InputStream getInputStream()throws FileNotFoundException { String path=ServletActionContext.getServletContext().getRealPath(inputPath); return new BufferedInputStream(new FileInputStream(path+"\\"+fileName)); } public void setInputStream(InputStream inputStream) { this.inputStream = inputStream; } public String getContentType() { return contentType; } public void setContentType(String contentType) { this.contentType = contentType; } @Override public String execute()throws Exception{ return "success"; } }
配置文件
框架
<action name="download" class="interceptor.FileDownAction">
<param name="savePath">/upload</param>
<result name="success" type="stream">
<param name="contentType">application/octet-stream</param>
<param name="inputName">inputStream</param>
<param name="contentDisposition">attachment;filename="${fileName}"</param>
<param name="bufferSize">4096</param>
</result>
</action>
contentType對應的文件類型
Word application/msword
Execl Application/vnd.ms-excel
PPT Application/vnd.ms-powerpoint
圖片 image/gif、image/bmp、image/jpeg
文本文件 text/plain
HTML網頁 text/html
可執行文件 application/octet-stream
jsp