Struts2_3_国际化处理_自定义拦截器_文件上传及下载_OGNL
Struts2國際化處理
瀏覽器根據當前的語言環境自動查找對應的語言環境資源包, 使jsp顯示合適的語言數據環境
Struts2實現國際化, 動作類必須繼承ActionSupport
Struts2中的攔截器
Struts2中很多功能都是攔截器完成的, 并且都是AOP思想的一種體現
自定義攔截器
繼承AbstractInterceptor類或實現Interceptor接口, 重寫intercept方法 配置攔截器, 攔截器只有在配置的條件下才能使用例如:
public class Demo1Interceptor extends AbstractInterceptor{public String intercept(ActionInvocation invocation) throws Exception{return null; } } //繼承AbstractInterceptor重寫intercept方法 聲明攔截器: struts.xml: <interceptors><interceptor name="demo1Interceptor" class="com.interceptors.Demo1Interceptor" /> </interceptors> 使用攔截器: <action name="action1" class="com.interceptors.Demo1Interceptor" method="save"><interceptor-ref name="demo1Interceptor"></interceptor-ref><result>/success.jsp</result> </action> 在interceptors標簽中可以配置多個攔截器聲明注:
使用攔截器必須先聲明然后再使用, 并且一旦配置了任何一個攔截器, 默認的攔截器就都失效了
攔截器執行順序
下面通過例子說明:
Struts.xml: <struts><constant name="struts.devMode" value="true"></constant><package name="p1" extends="struts-default"><!--聲明攔截器列表--><interceptors><interceptor name="demo1Interceptor" class="com.interceptors.Demo1Interceptor" /></interceptors><action name="action1" class="com.interceptors.Demo1Interceptor" method="save"><!--使用攔截器--><interceptor-ref name="demo1Interceptor"></interceptor-ref><result>/success.jsp</result></action></package> </struts> 在攔截器類中的ntercept方法有如下操作: public String intercept(ActionInvocation invocation) throws Exception{System.out.println("攔截器執行, 訪問動作方法之前");String result = invocation.invoke();System.out.println("攔截器執行, 訪問動作方法后");return result; }Action類: public class Demo1Action extends ActionSupport{public String save(){System.out.println("動作方法save執行");return SUCCESS;} }success.jsp: <body><%System.out.println("success.jsp執行了")%> </body> 當訪問save動作的時候有如下的運行順序:攔截器執行了, 分文動作之前動作方法save執行success.jsp執行了攔截器執行了, 訪問動作方法之后從上面的運行順序可以得出一下結論:
1.訪問動作方法之前一定會先執行所有的攔截操作
2.攔截操作執行完,必須使用invocation的invoke方法做放行操作, 此處的操作類似于Filter中的doFilter操作
3.當動作類, 以及結果視圖中的內容執行完之后又重新反向將攔截器都執行一遍
此處請看一下的Struts2的效果執行圖:
其實通過Struts2的執行圖就可以看出, 多個攔截器的運行過程, 在使用多個攔截器的時候, 它與單個攔截器的寫法一樣
intercept方法的返回值
正如上面例子看到的一樣, intercept方法具有一個String類型的返回值
String result = invocation.invoke();
此時的result就是代表結果視圖, 代表動作方法的返回值
解決自定義攔截器條件下, 默認攔截器出現無效的情況
正如前面提到的, 當我們使用自定義的攔截器的時候出現的問題就是, 默認系統提供的攔截器都會無效, 導致demo各種報錯
所以現在需要做的就是將Struts2提供的默認的攔截器加載到我們的配置文件中
有如下的解決方案:
但是上面的操作會暴露出一個問題: 就是每當我需要添加一個自定義的攔截器的時候都需要使用系統默認的攔截器, 重復代碼過多, 所以下面采取的措施就是, 將每個action中的攔截器抽取出來, 統一使用一個新的package管理, 然后在觸發action的時候使用攔截器
例如:
經過上面的修改之后, 在訪問動作A, B就不在需要進行攔截器的定義聲明操作, 但是由此也暴露出一個問題, 就是當訪問package p2下面的所有動作, 都將會觸發攔截器, 如果有的動作我們不想觸發攔截器, 那么就出現問題, 所以針對上面的問題, 有下面的解決方案
2. 繼承AbstractInterceptor的抽象子類MethodFilterInterceptor
MethodFilterInterceptor將AbstractInterceptor的抽象方法intercept重寫, 但是具有一個新的抽象方法doIntercept(ActionInvocation invocation);
MethodFilterInterceptor中具有兩個屬性:
Set< String> excludeMethods //哪些動作不需要攔截
Set< String> includeMethods //哪些動作需要攔截
上面的兩個屬性可以做注入操作, 通過配置struts.xml的方式做到配置攔截操作
所以在自定義攔截器的時候, extends MethodFilterInterceptor類, 實現doIntercept(ActionInvocation invocation);
注: 當我們需要進行方法攔截的時候, 就可以通過注入的方式, 進行指定攔截, 但是也暴露了一個問題, 如果只有在確定動作類, 動作方法之后才能確定param中的參數
所以針對這個問題, 有下面的解決方案:
攔截器類圖
// 從網上找的
Struts2的文件上傳與下載
文件上傳
與Servlet中的文件上傳一樣, Struts2中的文件上傳必須明確:
1.表單method為post
2.enctype取值必須是multipart/form-data
3.提供文件選擇域
下面使用Struts2提供的標簽進行演示:
注: Struts2中使用file標簽進行文件上傳, Struts2文件上傳的底層實現還是commons-fileupload和commons-io
動作類:
struts.xml:
<!--覆蓋默認的maxSize大小, 默認大小為2M--> <constant name="struts.multipart.maxSize" value="5242880"></constant> <package name="upload" extends="struts-default"><action name="upload" class="com.action.UploadAction" method="upload"><interceptor-ref name="defaultStack"><!--使用默認的fileUpload攔截器, 對extension做注入處理, 限制上傳文件擴展名--><param name="fileUpload.allowedExtension">jpg.png</param><!--限制上傳文件類型--><param name="fileUpload.allowedTypes">image/jpg, image/pjpeg,image/png</param></interceptor-ref><result name="input">/upload.jsp</result></action> </package>修改上傳文件出現的錯誤信息提示
當上傳文件的時候會出現, 文件類型/大小/后綴名…錯誤, 需要通過國際化的方式修改錯誤提示信息
有如下操作:
1.創建資源文件, 例如: fileuploadmessage.properties 放在src下
2.添加錯誤信息, 例如: struts.messages.error.uploading=上傳錯誤:{0}, 其余key查閱struts2-core.jar\org.apache.struts2\struts-message.properties, 只需要將value中英文值修改即可
3.在struts.xml中使用< constant name=“struts.custom.i18n.resource” value=“com…fileuploadmessage”/>, value代表資源文件位置
多文件上傳
多文件上傳, 在jsp中, 只需多添加file標簽, 在UploadAction中修改上傳字段, 上傳文件名, 上傳文件類型為數組/list類型即可, struts會自動將上傳的file分配到數組/list中
文件下載
文件下載是一種結果類型(Stream)
Action類: public class DownloadAction extends ActionSupport{private InputStream fileInputStream; //此處字段名不能寫in, 會報錯public String download() throws Exception{String filePath = ServletActionContext.getServletContext().getRealPath("/WEB-INF/files/1.jpg");fileInStream = new FileInputStream(filePath);return SUCCESS;}//下面一堆get, set操作, 進行注入 } struts.xml配置: <action name="download" class="com.action.DownloadAction" method="download"><result name="success" type="stream"><!--配置inputName屬性, 將action類中的輸入流--><param name="inputName">fileInputStream</param><!--設置響應消息頭, 告知瀏覽器以下載的方式打開--><param name="contentDisposition">attachment;filename=image.jpg</param><!--設置響應消息頭, 告知瀏覽器, 響應正文的MIME類型--><param name="contentType">application/octet-stream</param></result> </action> 注: 在寫filename會出現文件名寫死的情況, 所以采用OGNL表達式解決, 寫成: filename=${filename}, 在action類中獲取filename屬性, 注入處理OGNL
OGNL類似于EL表達式, Struts2表達式語言, 在Struts2中使用OGNL必須使用Struts2標簽庫
例:
在OGNL中可以調用普通方法, 靜態方法, 使用靜態變量, 但是在EL表達式中只能使用靜態方法
調用方法的時候, 需要寫出當前方法的完整路徑, 并且在路徑以及方法名前加"@"符號
當調用靜態方法的時候, 需要開啟OGNL靜態訪問: < constant name=“struts.ognl.allowStaticMethodAccess” value=“true”></ constant>
此時才能在OGNL中調用靜態方法
例:
在form表單中, radio以及check中就有OGNL的應用
例:
contextMap
contextMap主要用于存放每次動作訪問的數據
每次執行動作之前, 核心控制器StrutsPrepareAndExecuteFilter都會創建一個ActionContext和ValueStack對象。且每次動作訪問都會創建, 這兩個對象存儲了整個動作訪問期間用到的數據。并且把數據綁定到了線程局部變量(ThreadLocal)上
動作類是多例的, 每次動作訪問都會實例化, 確保線程安全
contextMap中存放的內容
注: 除valuestack是list, 其余都是map, contextMap也是map
未完待續~~
上面有錯, 還請指出, 如果認為我寫的還不錯, 還請點個贊, 多多支持一下, O(∩_∩)O~~
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的Struts2_3_国际化处理_自定义拦截器_文件上传及下载_OGNL的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql远程访问 linux_Linu
- 下一篇: jquery点击事件传值加载页面_jQu