您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關利用Spring MVC怎么實現一個文件上傳功能,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
1、使用Spring MVC 上傳文件必須配置文件解析器,如下:
<!-- 上傳文件攔截,設置最大上傳文件大小 10M=10*1024*1024(B)=10485760 bytes --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize" value="10485760" /> <property name="maxInMemorySize" value="10240000" /> <property name="defaultEncoding" value="UTF-8" /> </bean>
2、建立上傳文件表單代碼,其中要注意form表單中的enctype 屬性,必須存在且必須為multipart/form-data。還有當form中存在button標簽時,用ajax異步提交表單后,也面會被刷新。原因:button 存在時會再次提交一下表單,所以頁面被刷新了。
<!-- enctype 屬性值: 1、application/x-www-form-urlencoded 在發送前編碼所有字符(默認) 2、multipart/form-data 不對字符編碼。 在使用包含文件上傳控件的表單時,必須使用該值。 3、text/plain 空格轉換為 "+" 加號,但不對特殊字符編碼。 --> <div class="row"> <form method="post" enctype="multipart/form-data" id="form1"> <div><label>1、采用流的方式</label></div> <div class="col-sm-7" > <div class="input-group"> <input type="text" class="form-control" id="showFileInput1"> <input type="file" name="txtFile" id="uploadFileInput1" accept="text/plain"> <span class="input-group-addon" id="uploadFileButton1"> <span class="glyphicon glyphicon-folder-open"></span> <label>瀏覽</label> </span> </div> </div> <div class="col-sm-5"> <!-- 當form中存在button標簽時,用ajax異步提交表單后,也面會被刷新。(感覺很詭異) 原因:button 存在時會再次提交一下表單,所以頁面被刷新了。(之前認為button type='submit' 時)button才有提交表單的功能。 --> <a class="btn btn-default" id="submit1">上傳</a> </div> </form> </div>
3.1、使用CommonsMultipartFile接收上傳文件,其中要注意的是:方法中CommonsMultipartFile對應的變量名如果不是對應表單中文件輸入框<input type="file" name="txtFile" id="uploadFileInput1" accept="text/plain">的名稱就必須加上@RequestParam("txtFile") 強制注入。
/** * @Description: 通過文件流的形式上傳 * @param file @RequestParam("txtFile") 將name=txtFile控件得到的文件封裝成CommonsMultipartFile對象, * 如果不這樣做會報CommonsMultipartFile沒有初始化的錯誤 * java.lang.NoSuchMethodException: org.springframework.web.multipart.commons.CommonsMultipartFile.<init>() * @return * @author yuanfy * @date 2017年9月15日 下午4:36:11 * @version 6.5 */ @RequestMapping(value="test/upload1") @ResponseBody public String testUpload1(@RequestParam("txtFile")CommonsMultipartFile file){ Long times = System.currentTimeMillis(); if (file == null) { return null; } StringBuilder fileContent = new StringBuilder(); //1、獲取文件信息 FileUtils.getFileInfo(file, fileContent); //2、上傳文件并獲取文件內容 try { file.transferTo(new File("F:\\text.log"));//另存文件 fileContent.append(FileUtils.getFileContentByLine(file.getInputStream())); } catch (IOException e) { return "獲取文件內容失敗"; } //3、返回文件信息和內容 String content = fileContent.toString(); content = content.replace("times", (System.currentTimeMillis()-times) + "ms"); return content; }
界面效果圖如下:
3.2、使用CommonsMultipartResolver獲取存放文件對象,拿到文件對象后遍歷每個文件上傳及獲取相關的內容。
@RequestMapping(value="test/upload2") @ResponseBody public String testUpload2(HttpServletRequest request){ Long times = System.currentTimeMillis(); StringBuilder fileContent = new StringBuilder(); //1.根據servletContext獲取多文件上傳解析組件 CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext()); if (!multipartResolver.isMultipart(request)) { return "不是上傳文件表單,請檢查表單屬性"; } //2.將請求對象轉換為多文件請求對象。 MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request; //3、根據多文件請求對象獲取文件存放Map Map<String, MultipartFile> fileMap = multipartHttpServletRequest.getFileMap(); Iterator<Entry<String, MultipartFile>> iterator = fileMap.entrySet().iterator(); //4、迭代文件Map,獲取具體的MultipartFile while (iterator.hasNext()) { Entry<String, MultipartFile> entry = iterator.next(); MultipartFile multipartFile = entry.getValue(); //獲取文件頭信息 FileUtils.getFileInfo(multipartFile, fileContent); try { //上傳文件 multipartFile.transferTo(new File("F:\\text.log")); //獲取文件內容 fileContent.append(FileUtils.getFileContentByLine(multipartFile.getInputStream())); }catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } //5、返回文件信息和內容 String content = fileContent.toString(); content = content.replace("times", (System.currentTimeMillis()-times) + "ms"); return content; }
其中第一步獲取文件解析器對象應該都清楚只要在容器中配置了對應的對象我們就可以獲取到它,而它有根據上下文獲取的構造函數就方便多了。
/** * Constructor for standalone usage. Determines the servlet container's * temporary directory via the given ServletContext. * @param servletContext the ServletContext to use */ public CommonsMultipartResolver(ServletContext servletContext) { this(); setServletContext(servletContext); }
然后根據request判斷是否還有上傳文件的表單,如果不是肯定直接返回,我們看看源碼中是怎么判斷的。
//CommonsMultipartResolver.class 主要判斷request是否為空 @Override public boolean isMultipart(HttpServletRequest request) { return (request != null && ServletFileUpload.isMultipartContent(request)); } //ServletFileUpload 主要判斷是否是post方法,因為上傳文件必須是post提交,其實我們可以在我們自定義controller中的方法指定訪問 public static final boolean isMultipartContent(HttpServletRequest request) { if (!POST_METHOD.equalsIgnoreCase(request.getMethod())) { return false; } return FileUploadBase.isMultipartContent(new ServletRequestContext(request)); } //FileUploadBase.class 如果請求是MULTIPART 則返回true public static final boolean isMultipartContent(RequestContext ctx) { String contentType = ctx.getContentType();//類似:multipart/form-data; boundary=----WebKitFormBoundaryLF3eM94lDB0ocQxT if (contentType == null) { return false; } if (contentType.toLowerCase(Locale.ENGLISH).startsWith(MULTIPART)) { return true; } return false; }
所以如果request是上傳文件的請求對象,則進行第二步。將request轉換成多文件請求對象,然后獲取存放文件的map。
可想而知這種方法效率是比第一種要低的,因為他要遍歷文件map,但是在Spring MVC常用的卻是這種方法。
效果圖如下:
其中FileUtils.java代碼如下:
package com.yuanfy.monitorsite.common.util; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import org.springframework.web.multipart.MultipartFile; /** * @Description: 文件工具類方法 * @author yuanfy * @date 2017年9月15日 下午2:45:40 * @version 1.0 */ public class FileUtils { /** * @Description: 獲取文件信息 * @param file CommonsMultipartFile類型的文件 * @param fileContent StringBuilder,封裝文件信息 * @author yuanfy * @date 2017年9月15日 下午2:51:34 * @version 1.0 */ public static void getFileInfo(MultipartFile file, StringBuilder fileContent) { fileContent.append("文件名稱:\t\t").append(file.getName()).append("\n") .append("文件原始名稱:\t").append(file.getOriginalFilename()).append("\n") .append("文件大小:\t\t").append(file.getSize()).append("\n") .append("文件類型:\t\t").append(file.getContentType()).append("\n") .append("讀取文件時長:\t times").append("\n"); } /** * @Description: 根據文件對象獲取文件內容 * @param file * @author yuanfy * @date 2017年9月15日 下午5:01:57 * @version 1.0 * @throws IOException * @throws FileNotFoundException */ public static String getFileContentByLine(File file) throws FileNotFoundException, IOException { return getFileContentByLine(new FileInputStream(file)); } /** * @Description: 根據文件輸入流對象獲取文件內容 * @param in 文件輸入流對象 * @author yuanfy * @date 2017年9月15日 下午5:01:57 * @version 1.0 * @throws IOException */ public static String getFileContentByLine(InputStream in) throws IOException { StringBuilder fileContent = new StringBuilder(); byte[] bytes = new byte[1024]; int len = 0; while ((len = in.read(bytes)) != -1) { String content = new String(bytes, 0, len, "UTF-8"); fileContent.append(content); } StreamUtils.close(in); return fileContent.toString(); } }
以上就是利用Spring MVC怎么實現一個文件上傳功能,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。