Struts2學(xué)習(xí)手冊(cè)之文件上傳基礎(chǔ)教程
前言
我們?cè)陂_(kāi)發(fā)Web應(yīng)用時(shí),肯定要為用戶提供上傳的功能,比如用戶上傳一張圖像作為頭像等。為了能上傳文件,我們必須將表單的method設(shè)置為POST,將enctype設(shè)置為multipart/form-data
。只有在這種情況下,瀏覽器才會(huì)把用戶選擇文件的二進(jìn)制數(shù)據(jù)發(fā)送給服務(wù)器。這篇文章就對(duì)Struts2框架中的上傳功能進(jìn)行詳細(xì)的總結(jié),下面話不多說(shuō)了,來(lái)一起看看詳細(xì)的介紹吧。
Struts2的文件上傳
Struts2并未提供自己的請(qǐng)求解析器,也就是說(shuō),Struts2不會(huì)自己去處理multipart/form-data的請(qǐng)求,它需要調(diào)用其它上傳框架來(lái)解析二進(jìn)制請(qǐng)求數(shù)據(jù),但Struts2在原有的上傳解析器基礎(chǔ)上做了進(jìn)一步封裝,更進(jìn)一步簡(jiǎn)化了文件上傳。
在Struts2的default.properties
配置文件中,可以看到這樣的配置代碼:
### Parser to handle HTTP POST requests, encoded using the MIME-type multipart/form-data # struts.multipart.parser=cos # struts.multipart.parser=pell # struts.multipart.parser=jakarta-stream struts.multipart.parser=jakarta # uses javax.servlet.context.tempdir by default struts.multipart.saveDir= struts.multipart.maxSize=2097152
上述代碼主要用于配置Struts2上傳文件時(shí)的上傳解析器。Struts2的封裝隔離了底層文件上傳組件的區(qū)別,開(kāi)發(fā)者只要在此配置文件上傳所使用的解析器,就可以輕松地在不同的文件上傳框架之間切換。
Struts2默認(rèn)使用jakarta上傳解析器,當(dāng)然了,如果你不喜歡,你也可以換成別的。下面就通過(guò)代碼來(lái)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的基于Struts2的文件上傳功能。
實(shí)現(xiàn)文件上傳的Action
前臺(tái)頁(yè)面:
<form action="upload" method="post" enctype="multipart/form-data"> Title:<input type="text" name="title"><br> File:<input type="file" name="upload"><br> <input type="submit" value="submit"> </form>
Action類:
public class UploadAction extends ActionSupport { private String title; private File upload; private String uploadContentType; private String uploadFileName; private String savePath; public void setSavePath(String value) { this.savePath = value; } private String getSavePath() { String realPath = ServletActionContext.getServletContext().getRealPath("/WEB-INF/" + savePath); return realPath; } public void setTitle(String value) { this.title = value; } public String getTitle() { return title; } public void setUpload(File value) { this.upload = value; } public File getUpload() { return upload; } public void setUploadContentType(String value) { this.uploadContentType = value; } public String getFileContentType() { return uploadContentType; } public void setUploadFileName(String value) { this.uploadFileName = value; } public String getUploadFileName() { return uploadFileName; } @Override public String execute() throws Exception { FileOutputStream fos = new FileOutputStream(getSavePath() + "\\" + getUploadFileName()); FileInputStream fis = new FileInputStream(getUpload()); byte[] buffer = new byte[1024]; int len = 0; while ((len = fis.read(buffer)) > 0) { fos.write(buffer, 0, len); } fis.close(); fos.close(); return SUCCESS; } }
struts.xml配置文件:
<package name="upload" extends="struts-default"> <action name="upload" class="com.jellythink.practise.UploadAction"> <param name="savePath">/upload</param> <result name="success">/success.jsp</result> <result name="input">/index.jsp</result> </action> </package>
對(duì)于Action類中,包含了兩個(gè)特別的屬性:
- uploadContentType
- uploadFileName
這兩個(gè)屬性分別用于封裝上傳文件的文件名、上傳文件的文件類型。對(duì)于Struts2來(lái)說(shuō),如果Form表單中包含一個(gè)name屬性為xxx的文件域,則對(duì)應(yīng)的Action需要使用三個(gè)屬性來(lái)封裝該文件域的信息:
- 類型為File的xxx屬性封裝了該文件域?qū)?yīng)的文件內(nèi)容;
- 類型為String的xxxFileName屬性封裝了該文件域?qū)?yīng)的文件的文件名;
- 類型為String的xxxContentType屬性封裝了該文件域?qū)?yīng)的文件的文件類型。
通過(guò)上面的開(kāi)發(fā)過(guò)程,可以看出通過(guò)Struts2實(shí)現(xiàn)文件上傳確實(shí)是一件簡(jiǎn)單的事情。我們需要做的事情就是將文件域與Action中一個(gè)類型為File的屬性關(guān)聯(lián),就可以輕松訪問(wèn)到上傳文件的文件內(nèi)容,至于Struts2如何使用Multipart解析器,對(duì)開(kāi)發(fā)者完全透明。
手動(dòng)實(shí)現(xiàn)文件過(guò)濾
很多時(shí)候,Web應(yīng)用不允許用戶自由上傳,我們需要對(duì)用戶上傳的文件類型,文件大小進(jìn)行限制,因此必須在文件上傳過(guò)程中進(jìn)行文件過(guò)濾。下面就先手動(dòng)實(shí)現(xiàn)上傳文件過(guò)濾。
在struts.xml中配置一個(gè)新的參數(shù),表示支持的上傳類型:
<param name="allowTypes">image/png,image/gif,image/jpeg</param>
在Action中添加驗(yàn)證函數(shù):
// 進(jìn)行驗(yàn)證 @Override public void validate() { String filterResult = filterType(getAllowTypes().split(",")); if (filterResult != null) { addFieldError("upload", "您要上傳的文件類型不正確!"); } } public String filterType(String[] types) { String fileType = getFileContentType(); for (String type : types) { if (type.equals(fileType)) { return null; } } return ERROR; }
這只是實(shí)現(xiàn)了類型的判斷,然后在根據(jù)File類的length()
方法,來(lái)實(shí)現(xiàn)大小的驗(yàn)證。但是好麻煩,接下來(lái)就說(shuō)一種更簡(jiǎn)單的說(shuō)法。
攔截器實(shí)現(xiàn)文件過(guò)濾
Struts2提供了一個(gè)文件上傳的攔截器,通過(guò)配置攔截器可以更輕松地實(shí)現(xiàn)文件過(guò)濾。Struts2中文件上傳的攔截器fileUpload,為了讓該攔截器起作用,只需要在該Action中配置該攔截器引用即可。
配置fileUpload攔截器時(shí),可以為其指定兩個(gè)參數(shù):
- allowedTypes:該參數(shù)指定允許上傳的文件類型,多個(gè)文件類型之間以英文逗號(hào)隔開(kāi)
- maximumSize:該參數(shù)指定允許上傳的文件大小,單位是字節(jié)
<!-- 配置fileUpload攔截器 --> <interceptor-ref name="fileUpload"> <param name="allowedTypes">image/png,image/gif,image/jpeg</param> <param name="maximumSize">20000000</param> </interceptor-ref> <!-- 配置系統(tǒng)默認(rèn)的攔截器 --> <interceptor-ref name="defaultStack" /> <result name="success">/success.jsp</result> <result name="input">/index.jsp</result>
這樣子,修改配置就可以搞定的事情,比寫(xiě)一坨代碼真的輕松多了。
配置錯(cuò)誤信息
對(duì)于上傳出現(xiàn)錯(cuò)誤的情況,系統(tǒng)默認(rèn)都是提示英文的錯(cuò)誤信息,但是為了輸出國(guó)際化的提示信息,這就需要在國(guó)際化的資源配置文件中增加以下兩個(gè)key的消息定義:
struts.messages.error.content.type.not.allowed
=上傳文件類型不正確,請(qǐng)重新上傳struts.messages.error.file.too.large
=您上傳的文件太大,請(qǐng)重新上傳
接下來(lái)就可以使用<s:fielderror/>來(lái)輸出錯(cuò)誤信息了。
文件上傳的常量配置
在文章的開(kāi)始,我們說(shuō)到default.properties
中的配置,其中有一個(gè)struts.multipart.saveDir
配置,那么該配置項(xiàng)的具體作用是什么呢?
在Struts2執(zhí)行文件上傳的過(guò)程中,需要指定一個(gè)臨時(shí)文件夾,用來(lái)存放上傳過(guò)程中產(chǎn)生的臨時(shí)文件;如果沒(méi)有指定臨時(shí)文件夾,系統(tǒng)默認(rèn)使用javax.servlet.context.tempdir
,在Tomcat安裝路徑下的work/Catalina/localhost/路徑下。而這個(gè)struts.multipart.saveDir就是配置臨時(shí)文件的存放位置的。所以在開(kāi)發(fā)的過(guò)程中,一定要注意該目錄是否有讀寫(xiě)權(quán)限哦。
還有一個(gè)struts.multipart.maxSize
配置,該配置表示上傳文件的大小,如果同時(shí)指定了這個(gè)配置和fileUpload攔截器的maximumSize屬性,則先和struts.multipart.maxSize
配置的比較,再和fileUpload攔截器的maximumSize屬性比較,如果文件大小超過(guò)了struts.multipart.maxSize
配置的,則會(huì)出現(xiàn)異常,并不會(huì)將Result轉(zhuǎn)到input,這個(gè)一定要注意。
總結(jié)
這篇文章詳細(xì)的總結(jié)了Struts2中的文件上傳,內(nèi)容有點(diǎn)多,基本都是手冊(cè)上的內(nèi)容,也罷,就當(dāng)手冊(cè)了。
好了,以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
- java中struts2實(shí)現(xiàn)文件上傳下載功能實(shí)例解析
- struts2單個(gè)文件上傳的兩種實(shí)現(xiàn)方式
- 關(guān)于Struts2文件上傳與自定義攔截器
- Struts2+jquery.form.js實(shí)現(xiàn)圖片與文件上傳的方法
- JavaWeb中struts2實(shí)現(xiàn)文件上傳下載功能實(shí)例解析
- JavaEE中struts2實(shí)現(xiàn)文件上傳下載功能實(shí)例解析
- java中struts2實(shí)現(xiàn)簡(jiǎn)單的文件上傳與下載
- struts2+jsp實(shí)現(xiàn)文件上傳的方法
- struts2實(shí)現(xiàn)多文件上傳的示例代碼
- java中Struts2文件上傳問(wèn)題詳解
相關(guān)文章
Java并發(fā)編程之顯示鎖ReentrantLock和ReadWriteLock讀寫(xiě)鎖
這篇文章主要介紹了Java并發(fā)編程之顯示鎖ReentrantLock和ReadWriteLock讀寫(xiě)鎖,本文講解了ReentrantLock概況、Lock接口、Lock使用、輪詢鎖的和定時(shí)鎖、公平性、可中斷獲鎖獲取操作等內(nèi)容,需要的朋友可以參考下2015-04-04spring?boot?mybatis日志輸出到控制臺(tái)的方法實(shí)踐
在開(kāi)發(fā)過(guò)程中我們往往需要打印出SQL語(yǔ)句,這樣就方便我們監(jiān)控問(wèn)題,本文主要介紹了spring?boot?mybatis日志輸出到控制臺(tái)的方法實(shí)踐,具有一定的參考價(jià)值,感興趣的可以了解一下2024-05-05spring boot+vue 的前后端分離與合并方案實(shí)例詳解
這篇文章主要介紹了spring boot+vue 的前后端分離與合并方案實(shí)例詳解,需要的朋友可以參考下2017-11-11解決@Api注解不展示controller內(nèi)容的問(wèn)題
這篇文章主要介紹了解決@Api注解不展示controller內(nèi)容的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。2022-01-01springboot打印接口調(diào)用日志的實(shí)例
這篇文章主要介紹了springboot打印接口調(diào)用日志的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09SpringBoot 2 統(tǒng)一異常處理過(guò)程解析
這篇文章主要介紹了SpringBoot 2 統(tǒng)一異常處理過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09Java練習(xí)之潛艇小游戲的實(shí)現(xiàn)
這篇文章主要和大家分享一個(gè)Java小練習(xí)——利用Java編寫(xiě)一個(gè)潛艇小游戲,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2022-03-03在Java 8中將List轉(zhuǎn)換為Map對(duì)象方法
這篇文章主要介紹了在Java 8中將List轉(zhuǎn)換為Map對(duì)象方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-11-11