JavaWeb中struts2實(shí)現(xiàn)文件上傳下載功能實(shí)例解析
在做B/S系統(tǒng)時(shí),通常會(huì)涉及到上傳文件和下載文件,在沒接struts2框架之前,我們都是使用apache下面的commons子項(xiàng)目的FileUpload組件來進(jìn)行文件的上傳,但是那樣做的話,代碼看起來比較繁瑣,而且不靈活,在學(xué)習(xí)了struts2后,struts2為文件上傳下載提供了更好的實(shí)現(xiàn)機(jī)制,在這里我分別就單文件上傳和多文件上傳的源代碼進(jìn)行一下講解,這里需要導(dǎo)入文件下載上傳的兩個(gè)jar文件,一個(gè)是commons-fileupload-1.2.2.jar,另一個(gè)是commons-io-2.0.1.jar
struts2單文件上傳:
首先是一個(gè)jsp文件上傳頁面,這個(gè)比較簡單,就是一個(gè)表單,里面有個(gè)文件上傳框
<!--在進(jìn)行文件上傳時(shí),表單提交方式一定要是post的方式,因?yàn)槲募蟼鲿r(shí)二進(jìn)制文件可能會(huì)很大,還有就是enctype屬性,這個(gè)屬性一定要寫成multipart/form-data, 不然就會(huì)以二進(jìn)制文本上傳到服務(wù)器端--> <form action="fileUpload.action" method="post" enctype="multipart/form-data"> username: <input type="text" name="username"><br> file: <input type="file" name="file"><br> <input type="submit" value="submit"> </form>
接下來是FileUploadAction部分代碼,因?yàn)閟truts2對(duì)上傳和下載都提供了很好的實(shí)習(xí)機(jī)制,所以在action這段我們只需要寫很少的代碼就行:
public class FileUploadAction extends ActionSupport { private String username; //注意,file并不是指前端jsp上傳過來的文件本身,而是文件上傳過來存放在臨時(shí)文件夾下面的文件 private File file; //提交過來的file的名字 private String fileFileName; //提交過來的file的MIME類型 private String fileContentType; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public File getFile() { return file; } public void setFile(File file) { this.file = file; } public String getFileFileName() { return fileFileName; } public void setFileFileName(String fileFileName) { this.fileFileName = fileFileName; } public String getFileContentType() { return fileContentType; } public void setFileContentType(String fileContentType) { this.fileContentType = fileContentType; } @Override public String execute() throws Exception { String root = ServletActionContext.getServletContext().getRealPath("/upload"); InputStream is = new FileInputStream(file); OutputStream os = new FileOutputStream(new File(root, fileFileName)); System.out.println("fileFileName: " + fileFileName); // 因?yàn)閒ile是存放在臨時(shí)文件夾的文件,我們可以將其文件名和文件路徑打印出來,看和之前的fileFileName是否相同 System.out.println("file: " + file.getName()); System.out.println("file: " + file.getPath()); byte[] buffer = new byte[500]; int length = 0; while(-1 != (length = is.read(buffer, 0, buffer.length))) { os.write(buffer); } os.close(); is.close(); return SUCCESS; } }
首先我們要清楚一點(diǎn),這里的file并不是真正指代jsp上傳過來的文件,當(dāng)文件上傳過來時(shí),struts2首先會(huì)尋找struts.multipart.saveDir(這個(gè)是在default.properties里面有)這個(gè)name所指定的存放位置,我們可以新建一個(gè)struts.properties屬性文件來指定這個(gè)臨時(shí)文件存放位置,如果沒有指定,那么文件會(huì)存放在tomcat的apache-tomcat-7.0.29\work\Catalina\localhost\目錄下,然后我們可以指定文件上傳后的存放位置,通過輸出流將其寫到流里面就行了,這時(shí)我們就可以在文件夾里看到我們上傳的文件了。
文件上傳后我們還需要將其下載下來,其實(shí)struts2的文件下載原理很簡單,就是定義一個(gè)輸入流,然后將文件寫到輸入流里面就行,關(guān)鍵配置還是在struts.xml這個(gè)配置文件里配置:
FileDownloadAction代碼如下:
public class FileDownloadAction extends ActionSupport { public InputStream getDownloadFile() { return ServletActionContext.getServletContext().getResourceAsStream("upload/通訊錄2012年9月4日.xls"); } @Override public String execute() throws Exception { return SUCCESS; } }
我們看,這個(gè)action只是定義了一個(gè)輸入流,然后為其提供getter方法就行,接下來我們看看struts.xml的配置文件:
<action name="fileDownload" class="com.xiaoluo.struts2.FileDownloadAction"> <result name="success" type="stream"> <param name="contentDisposition">attachment;filename="通訊錄2012年9月4日.xls"</param> <param name="inputName">downloadFile</param> </result> </action>
struts.xml配置文件有幾個(gè)地方我們要注意,首先是result的類型,以前我們定義一個(gè)action,result那里我們基本上都不寫type屬性,因?yàn)槠淠J(rèn)是請(qǐng)求轉(zhuǎn)發(fā)(dispatcher)的方式,除了這個(gè)屬性一般還有redirect(重定向)等這些值,在這里因?yàn)槲覀冇玫氖俏募螺d,所以type一定要定義成stream類型,告訴action這是文件下載的result,result元素里面一般還有param子元素,這個(gè)是用來設(shè)定文件下載時(shí)的參數(shù),inputName這個(gè)屬性就是得到action中的文件輸入流,名字一定要和action中的輸入流屬性名字相同,然后就是contentDisposition屬性,這個(gè)屬性一般用來指定我們希望通過怎么樣的方式來處理下載的文件,如果值是attachment,則會(huì)彈出一個(gè)下載框,讓用戶選擇是否下載,如果不設(shè)定這個(gè)值,那么瀏覽器會(huì)首先查看自己能否打開下載的文件,如果能,就會(huì)直接打開所下載的文件,(這當(dāng)然不是我們所需要的),另外一個(gè)值就是filename這個(gè)就是文件在下載時(shí)所提示的文件下載名字。在配置完這些信息后,我們就能過實(shí)現(xiàn)文件的下載功能了。
struts2多文件上傳:
其實(shí)多文件上傳和單文件上傳原理一樣,單文件上傳過去的是單一的File,多文件上傳過去的就是一個(gè)List<File>集合或者是一個(gè)File[]數(shù)組,首先我們來看一下前端jsp部分的代碼,這里我用到了jquery來實(shí)現(xiàn)動(dòng)態(tài)的添加文件下載框以及動(dòng)態(tài)的刪除下載框:
<script type="text/javascript" src="script/jquery-1.8.1.js"></script> <script type="text/javascript"> $(function() { $("#button").click(function() { var html = $("<input type='file' name='file'>"); var button = $("<input type='button' name='button' value='刪除'><br>"); $("#body div").append(html).append(button); button.click(function() { html.remove(); button.remove(); }) }) }) </script> </head> <body id="body"> <form action="fileUpload2.action" method="post" enctype="multipart/form-data"> username: <input type="text" name="username"><br> file: <input type="file" name="file"> <input type="button" value="添加" id="button"><br> <div></div> <input type="submit" value="submit"> </form> </body>
file的名字必須都命名成file才行,然后處理多文件上傳的action代碼如下:
public class FileUploadAction2 extends ActionSupport { private String username; //這里用List來存放上傳過來的文件,file同樣指的是臨時(shí)文件夾中的臨時(shí)文件,而不是真正上傳過來的文件 private List<File> file; //這個(gè)List存放的是文件的名字,和List<File>中的文件相對(duì)應(yīng) private List<String> fileFileName; private List<String> fileContentType; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public List<File> getFile() { return file; } public void setFile(List<File> file) { this.file = file; } public List<String> getFileFileName() { return fileFileName; } public void setFileFileName(List<String> fileFileName) { this.fileFileName = fileFileName; } public List<String> getFileContentType() { return fileContentType; } public void setFileContentType(List<String> fileContentType) { this.fileContentType = fileContentType; } @Override public String execute() throws Exception { String root = ServletActionContext.getServletContext().getRealPath("/upload"); for(int i = 0; i < file.size(); i++) { InputStream is = new FileInputStream(file.get(i)); OutputStream os = new FileOutputStream(new File(root, fileFileName.get(i))); byte[] buffer = new byte[500]; @SuppressWarnings("unused") int length = 0; while(-1 != (length = is.read(buffer, 0, buffer.length))) { os.write(buffer); } os.close(); is.close(); } return SUCCESS; } }
這樣同樣將其寫到一個(gè)輸出流里面,這樣我們就可以在文件夾里看到上傳的多個(gè)文件了
接下來的文件下載就和剛才的文件下載一模一樣,struts.xml也是一樣的,這里就不再重復(fù)了
總結(jié):總的來說,struts2提供的文件上傳下載機(jī)制簡化了我們很多代碼,我們可以在以后的項(xiàng)目中使用該機(jī)制,同樣我們也可以使用FileUpload組件來進(jìn)行文件的上傳,這個(gè)都是因個(gè)人愛好決定!
關(guān)于JavaWeb中的文件上傳和下載功能的內(nèi)容就這么多,謝謝大家的閱讀。
- JavaWeb實(shí)現(xiàn)文件上傳下載功能實(shí)例解析
- JavaWeb實(shí)現(xiàn)文件上傳下載功能實(shí)例詳解
- Javaweb實(shí)現(xiàn)上傳下載文件的多種方法
- JavaWeb文件上傳下載實(shí)例講解(酷炫的文件上傳技術(shù))
- JavaWeb項(xiàng)目實(shí)現(xiàn)文件上傳動(dòng)態(tài)顯示進(jìn)度實(shí)例
- JavaWeb實(shí)現(xiàn)多文件上傳及zip打包下載
- JavaWeb實(shí)現(xiàn)文件上傳與下載的方法
- javaweb實(shí)現(xiàn)文件上傳示例代碼
- JavaWeb實(shí)現(xiàn)文件上傳與下載實(shí)例詳解
- JavaWeb實(shí)現(xiàn)簡單上傳文件功能
相關(guān)文章
Java實(shí)現(xiàn)斷點(diǎn)下載功能的示例代碼
當(dāng)下載一個(gè)很大的文件時(shí),如果下載到一半暫停,如果繼續(xù)下載呢?斷點(diǎn)下載就是解決這個(gè)問題的。本文將用Java語言實(shí)現(xiàn)斷點(diǎn)下載,需要的可以參考一下2022-05-05Java構(gòu)造函數(shù)的相互調(diào)用代碼示例
這篇文章主要介紹了Java構(gòu)造函數(shù)的相互調(diào)用代碼示例,分享了兩段代碼示例,通過this關(guān)鍵字實(shí)現(xiàn)對(duì)的構(gòu)造函數(shù)的調(diào)用,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11關(guān)于shiro中部分SpringCache失效問題的解決方法
這篇文章主要給大家介紹了關(guān)于shiro中部分SpringCache失效問題的解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-07-07Eclipse+Java+Swing+Mysql實(shí)現(xiàn)工資管理系統(tǒng)
這篇文章主要介紹了Eclipse+Java+Swing+Mysql實(shí)現(xiàn)工資管理系統(tǒng),對(duì)正在工作或者學(xué)習(xí)的你有一定的參考價(jià)值,需要的朋友可以參考一下2022-01-01