使用SpringMVC如何實(shí)現(xiàn)一個(gè)文件上傳功能?很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。
讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來(lái)自于我們對(duì)這個(gè)行業(yè)的熱愛。我們立志把好的技術(shù)通過(guò)有效、簡(jiǎn)單的方式提供給客戶,將通過(guò)不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長(zhǎng)期合作伙伴,公司提供的服務(wù)項(xiàng)目有:域名注冊(cè)、虛擬空間、營(yíng)銷軟件、網(wǎng)站建設(shè)、吳忠網(wǎng)站維護(hù)、網(wǎng)站推廣。
說(shuō)明:
文件上傳的途徑
文件上傳主要有兩種方式:
1.使用Apache Commons FileUpload元件。
2.利用Servlet3.0及其更高版本的內(nèi)置支持。
客戶端編程
1.為了上傳文件,必須將HTML表格的enctype屬性值設(shè)為multipart/form-data,像下面這樣:
<form action="action" enctype="multipart/form-data" method="post"> Select a file<input type="file" name="fieldName"/> <input type="submit" value="Upload"/> </form>
2.在HTML5之前,如果要想上傳多個(gè)文件,必須使用多個(gè)文件input元素。但是,在HTML5中,通過(guò)在input元素中引入多個(gè)multiple屬性,使得多個(gè)文件的上傳變得更加簡(jiǎn)單,下面均可使一個(gè)上傳框支持多個(gè)文件上傳。
<input type="file" name="fieldName" multiple/> <input type="file" name="fieldName" multiple="multiple"/> <input type="file" name="fieldName" multiple=""/>
MultipartFile接口
在SpringMVC中處理已經(jīng)上傳的文件十分簡(jiǎn)單,上傳到SpringMVC應(yīng)用程序中的文件會(huì)被包在一個(gè)MultipartFile對(duì)象中,你唯一要做的事情就是用類型為MultipartFile的屬性編寫一個(gè)Domain類。就像下面這樣:
package domain; import org.springframework.web.multipart.MultipartFile; import java.io.Serializable; import java.util.List; public class Product implements Serializable { //實(shí)現(xiàn)了這個(gè)接口,可以安全的將數(shù)據(jù)保存到HttpSession中 private long id; private String name; private String description; private String price; //在Domain類中加入MultipartFile類型的屬性,用來(lái)保存上傳的文件 private List<MultipartFile> images; public List<MultipartFile> getImages() { return images; } public void setImages(List<MultipartFile> images) { this.images = images; } ......多個(gè)get和set方法。
MultipartFile接口提供了以下方法:
Modifier and Type | Method and Description |
---|---|
byte[] | getBytes()Return the contents of the file as an array of bytes. |
String | getContentType()Return the content type of the file. |
InputStream | getInputStream()Return an InputStream to read the contents of the file from. |
String | getName()Return the name of the parameter in the multipart form. |
String | getOriginalFilename()Return the original filename in the client's filesystem. |
long | getSize()Return the size of the file in bytes. |
boolean | isEmpty()Return whether the uploaded file is empty, that is, either no file hasbeen chosen in the multipart form or the chosen file has no content. |
void | transferTo(File dest)Transfer the received file to the given destination file. |
實(shí)例:用CommonsFileUpLoad上傳文件
導(dǎo)入Jar包及配置環(huán)境變量
編寫視圖
代碼:
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Add Product Form</title> </head> <body> <form:form action="product_save" method="post" commandName="product" enctype="multipart/form-data"> <fieldset> <legend>Add a Product</legend> <p> <label for="name">ProductName</label> <form:input type="text" id="name" name="name" tabindex="1" path="name"/> </p> <p> <label for="description">ProductDescription</label> <form:input type="text" id="description" name="description" tabindex="2" path="description"/> </p> <p> <label for="price">ProductPrice</label> <form:input type="text" id="price" name="price" tabindex="3" path="price"/> </p> <p> <label for="image">ProductImage</label> <input type="file" name="images[0]"> </p> <p> <input type="reset"> <input type="submit"> </p> </fieldset> </form:form> </body> </html>
說(shuō)明:
首先為了上傳文件,必須將HTML表格的enctype屬性值設(shè)為multipart/form-data
其次,在HTML5之前,如果要想上傳多個(gè)文件,必須要用到多個(gè)文件input元素。
但是在HTML5,通過(guò)在Input元素中引入過(guò)個(gè)multiple屬性,使得多個(gè)文件上傳變得更加簡(jiǎn)單。
<input type="file" name="fieldName" multiple/> <input type="file" name="fieldName" multiple="multiple"/> <input type="file" name="fieldName" multiple=""/>
圖示:
編寫控制器
package controller; import domain.Product; import Service.ProductService; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import java.io.File; import java.io.IOException; import java.util.List; @Controller public class ProductController { private static final Log logger=LogFactory.getLog(ProductController.class); @Autowired private ProductService productService; @RequestMapping(value = "/product_input") public String inputProduct(Model model) { logger.info("inputProduct called"); model.addAttribute("product",new Product()); return "ProductForm"; } @RequestMapping(value = "/product_save",method = RequestMethod.POST) public String saveProduct(HttpServletRequest servletRequest, @ModelAttribute Product product, BindingResult bindingResult,Model model) { List<MultipartFile> files= product.getImages(); System.out.println("文件數(shù)量是"+files.size()); if(null!=files&&files.size()>0) { for (MultipartFile file:files) { String fileName=file.getOriginalFilename(); //獲得文件名稱 File imagFile = new File(servletRequest.getServletContext().getRealPath("/image"),fileName);try { file.transferTo(imagFile);//用于將文件寫到服務(wù)器本地 } catch (IOException e) { e.printStackTrace(); } } } model.addAttribute("product",product); return "ProductDetails"; } @RequestMapping(value = "/product_view/{id}") public String viewProduct(@PathVariable Long id,Model model) { Product product =productService.get(id); model.addAttribute("product",product); return "ProductDetails"; } }
配置文件
你可以看到我們?cè)赟pringMVC的配置文件中配置了一個(gè)名為multipartResolver的Bean。
基于servlet的multipartresolver實(shí)現(xiàn)Apache Commons FileUpload 1.2或以上。
提供“maxuploadsize”、“maxinmemorysize”和“defaultencoding”設(shè)置bean的屬性(繼承commonsfileuploadsupport)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> <context:component-scan base-package="controller"/> <context:component-scan base-package="Service"/> <!-- <mvc:annotation-driven>元素注冊(cè)用于支持基于注解的控制器的請(qǐng)求處理方法的Bean對(duì)象。 詳解:https://my.oschina.net/HeliosFly/blog/205343 --> <mvc:annotation-driven></mvc:annotation-driven> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/view/"/> <property name="suffix" value=".jsp"/> </bean> <!--resources 元素指示SpringMVC那些靜態(tài)資源需要單獨(dú)處理--> <mvc:resources mapping="/image/**" location="/image/"/> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize" value="2000000"/> </bean> </beans>
說(shuō)明:
resources 元素指示SpringMVC那些靜態(tài)資源需要單獨(dú)處理,此處我們要單獨(dú)處理的是image,如果不單獨(dú)處理而是經(jīng)過(guò)dispatcher的話,就會(huì)發(fā)生404錯(cuò)誤.
實(shí)例:用Servlet3及其更高版本上傳文件
說(shuō)明:
有了Servlet3,就不需要Commons FileUpload 和Commons IO元件了.因?yàn)樵赟ervlet3中內(nèi)置了上傳文件的特性.
幸運(yùn)的是Domain類和Controller類基本不變,我們僅僅需要修改一下配置文件。
配置文件:
修改Web.xml
我們可以看到實(shí)在dispatcher的基礎(chǔ)上添加了配置項(xiàng):multipart-config
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> <multipart-config> <max-file-size>20848820</max-file-size> <!--上傳內(nèi)文件的最大容量--> <max-request-size>418018841</max-request-size> <!--表示多部分HTTP請(qǐng)求允許的最大容量--> <file-size-threshold>1048576</file-size-threshold> <!--超過(guò)這個(gè)容量將會(huì)被寫到磁盤中--> <location>/image/</location> <!--要將已上傳的文件保存到磁盤中的位置--> </multipart-config> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!--Spring中文亂碼攔截器--> <filter> <filter-name>setcharacter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>setcharacter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
SpringMVC配置文件添加多部分解析器
MultipartResolver接口的標(biāo)準(zhǔn)實(shí)現(xiàn),基于Servlet 3.0部分API. To be added as "multipartResolver" bean to a Spring DispatcherServlet context, without any extra configuration at the bean level. <bean id="MultipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver"></bean>
實(shí)例:為多文件上傳添加一個(gè)進(jìn)度條
說(shuō)明:
我們關(guān)注的是HTML5 input元素的change事件,當(dāng)input元素的值發(fā)生改變時(shí),他就會(huì)被觸發(fā)。其次,我們還關(guān)注XMLHttpRequest對(duì)象中添加progress事件。XMLHttpRequest自然是AJAX的骨架。當(dāng)異步使用XMLHttpRequest對(duì)象上傳文件的時(shí)候就會(huì)持續(xù)地觸發(fā)progress事件,直到上傳進(jìn)度完成或者取消。通過(guò)輕松監(jiān)聽progress事件,可以輕松地檢測(cè)文件上傳操作的進(jìn)度。
編寫Domain和Controller
1.Domain:UploadFile
package domain; import org.springframework.web.multipart.MultipartFile; import java.io.Serializable; public class UploadFile implements Serializable { private MultipartFile multipartFile; public MultipartFile getMultipartFile() { return multipartFile; } public void setMultipartFile(MultipartFile multipartFile) { this.multipartFile = multipartFile; } }
2.Controller:Html5FileUploadController類
package controller; import domain.UploadFile; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import java.io.File; @Controller public class Html5FileUploadController { private static final Log logger = LogFactory.getLog(Html5FileUploadController.class); @RequestMapping("/html5") public String inputProduct() { return "html5"; } @RequestMapping("/file_upload") public void saveFile(HttpServletRequest servletRequest, @ModelAttribute UploadFile file, BindingResult result) { MultipartFile multipartFile =file.getMultipartFile(); String filename =multipartFile.getOriginalFilename(); try { File file1 = new File(servletRequest.getServletContext().getRealPath("/image"),filename); multipartFile.transferTo(file1); System.out.println("已經(jīng)寫人本地文件:"+file1.getName()); } catch (Exception e) { e.printStackTrace(); } } }
編寫HTML5頁(yè)面
<%-- Created by IntelliJ IDEA. User: zy Date: 17-3-8 Time: 下午10:01 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <script> var totalFileLength,totalUploaded,fileCount,filesUploaded; function debug(s) { //輸出調(diào)試信息 var debug = document.getElementById('debug'); if(debug) { debug.innerHTML =debug.innerHTML+'</br>'+s; } } function onUploadComplete(e) { //當(dāng)一個(gè)文件上傳完成,緊接著開始調(diào)用下次upLoadNext(); totalUploaded+=document.getElementById('files').files[filesUploaded].size; filesUploaded++; debug('Complete'+filesUploaded+" of "+fileCount); debug('totalUploaded:'+totalUploaded); if(filesUploaded<fileCount) { upLoadNext(); } } function onUploadFailed() { alert("Error uploading file"); } function onUploadProgress(e) {//當(dāng)進(jìn)度發(fā)生改變時(shí),改變進(jìn)度條 if(e.lengthComputable) { var percentComplete =parseInt((e.loaded+totalUploaded)*100/totalFileLength); var bar = document.getElementById("bar"); bar.style.width=percentComplete+"%"; bar.innerHTML =percentComplete+"% complete"; } else { debug('unable to compute'); } } function upLoadNext() { //將XMLHttpRequest對(duì)象的progress事件添加到onLoadProgress并將load事件和error事件分別綁定到對(duì)應(yīng)方法。 var xhr = new XMLHttpRequest(); var fd =new FormData(); var file =document.getElementById('files').files[filesUploaded]; fd.append("multipartFile",file); xhr.upload.addEventListener("progress",onUploadProgress,false); xhr.addEventListener("load",onUploadComplete,false); xhr.addEventListener("error",onUploadFailed,false); xhr.open("POST","file_upload"); debug('uploading'+file.name); xhr.send(fd); } function onFileSelect(e) { //當(dāng)選擇的文件發(fā)生改變時(shí),重新獲取并打印現(xiàn)在所選的文件信息 var files =e.target.files; var output=[]; fileCount =files.length; totalFileLength =0; for(var i=0;i<fileCount;i++) { var file =files[i]; output.push(file.name,'(',file.size,'bytes',')',file.lastModifiedDate.toLocaleDateString()); output.push("<br/>"); debug('add'+file.size); totalFileLength+=file.size; } document.getElementById('selectedFiles').innerHTML = output.join(''); debug('totalFileLength:'+totalFileLength); } function startUpload() { //當(dāng)用戶點(diǎn)擊提交以后開始執(zhí)行 totalUploaded=filesUploaded=0; upLoadNext(); } window.onload=function () { document.getElementById('files').addEventListener('change',onFileSelect,false); document.getElementById('upLoadButton').addEventListener('click',startUpload,false); } </script> </body> <h2>Multipart File Uploads with Progress Bar</h2> <div id="bar" > </div> <form> <input type="file" id="files" multiple> <br> <output id="selectedFiles"></output> <input id="upLoadButton" type="button" value="Upload"> </form> <div id="debug" > </div> </html>
說(shuō)明:
progressBar div用于展示上傳進(jìn)度,debug div用于顯示調(diào)試信息。
執(zhí)行腳本時(shí),第一件事就是為4個(gè)變量分配空間:totalFileLength,totalUploaded,fileCount,filesUploaded;
看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對(duì)創(chuàng)新互聯(lián)的支持。
網(wǎng)頁(yè)標(biāo)題:使用SpringMVC如何實(shí)現(xiàn)一個(gè)文件上傳功能
網(wǎng)站URL:http://muchs.cn/article28/pihocp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)、小程序開發(fā)、虛擬主機(jī)、網(wǎng)站排名、網(wǎng)站策劃、商城網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)