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