檔案上傳優化
阿新 • • 發佈:2018-12-09
一、思路:
(1)可移植性(利用properties檔案配置檔案儲存位置)
(2)獲取檔案字尾名
(3)生成新的檔名(UUID)
(4)單檔案儲存,並返回新的檔案的儲存地址(包括新的檔名)
(5)多檔案儲存(List<檔案資訊類>)
(3)儘量減少查詢次數(資料夾分割槽(根據檔案型別和上傳日期進行))
二、實踐
(1)匯入包
spring-web
spring-mvc
common-fileUpload
common-io
(2)可移植性
/springMVCdemo/src/fileUpload.properties檔案
imgPath=d\:\\myImg\\ txtPath=d\:\\myTxt\\ exePath=d\:\\myExe\\ pdfPath=d\:\\myPdf\\ imgSuffixs=jpg~jpeg~gif~png imgType=image
(3)在spring-mvc.xml檔案的基本配置的前提下,新增以下配置
<!--——————————————————————————————————————————————————————————————————檔案上傳配置——————————————————————————————————————————————————————————————————————————————————— --> <!--檔案上傳使用, 配置multipartResolver,id名為約定好的"multipartResolver",不可更改,否則會報錯 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 上傳檔案的最大值,如限制20M以內:20*1024*1024=52428800 --> <property name="maxUploadSize" value="52428800"/> <!-- 編碼方式 --> <property name="defaultEncoding" value="UTF-8"/> <!-- 快取大小 ,比如1M:1024*1024=1048576--> <property name="maxInMemorySize" value="1048576"/> </bean> <!--——————————————————————————————————————————————————————————————————properties檔案資訊注入(增強可移植性)———————————————————————————————————————————————————————————————— --> <!--PropertiesFactoryBean對properties檔案可用 ,可以用來注入properties配置檔案的資訊 --> <bean id="fileUploadProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> <property name="location" value="classpath:fileUpload.properties"/> </bean>
(4)編寫檔案上傳工具類
FileInfo 檔案資訊包裝類
package pojo; public class FileInfo { private String NewName;//新檔名 private String NewFilePath;//新檔案的儲存路徑 private String contentType;//檔案型別 private String originalFilename;//檔案原名 private long size;//檔案大小 private String formFieldName;//表單控制元件名 public String getNewName() { return NewName; } public void setNewName(String newName) { NewName = newName; } public String getNewFilePath() { return NewFilePath; } public void setNewFilePath(String newFilePath) { NewFilePath = newFilePath; } public String getContentType() { return contentType; } public void setContentType(String contentType) { this.contentType = contentType; } public String getOriginalFilename() { return originalFilename; } public void setOriginalFilename(String originalFilename) { this.originalFilename = originalFilename; } public long getSize() { return size; } public void setSize(long size) { this.size = size; } public String getFormFieldName() { return formFieldName; } public void setFormFieldName(String formFieldName) { this.formFieldName = formFieldName; } @Override public String toString() { return "檔案資訊 [新檔名:" + NewName + ", 新檔案的儲存路徑:" + NewFilePath + ", 檔案型別:" + contentType + ", 檔案原名:" + originalFilename + ", 檔案大小:" + size + ", 表單控制元件名:" + formFieldName + "]"; } }
MyFileUtil 檔案上傳工具類
package utils;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import pojo.FileInfo;
@Component(value="fileUtils") //普通的bean注入
public class MyFileUtil {
/*為了保證私有屬性的資料安全性,這個類的屬性不能定義為靜態*/
private String path; //"註解"對"靜態引用"無效
private String[] suffixs; //檔名字尾陣列
private String type;//檔案型別
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String[] getSuffixs() {
return suffixs;
}
/*引數為"檔名字尾陣列字串"*/
public void setSuffixs(String suffixsStr) {
String[] suffixs =null;
// 如果檔名字尾陣列字串不為空
if (null != suffixsStr) {
// 分割檔名字尾陣列字串
suffixs = suffixsStr.split("~");
}
this.suffixs = suffixs;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
/*擷取檔案原名的字尾名*/
public String getSuffix(MultipartFile tempFile){
//呼叫common-fileUpload.jar中的工具類FilenameUtils
return FilenameUtils.getExtension(tempFile.getOriginalFilename());
}
/*建立檔案的新名稱*/
public String getNewName(MultipartFile tempFile){
return UUID.randomUUID().toString()+"."+getSuffix(tempFile);
}
/*單檔案儲存,並封裝檔案資訊*/
private void upload(MultipartFile tempFile,FileInfo info) throws Exception{
String newName = getNewName(tempFile);
//呼叫common-fileUpload.jar中的工具類FileUtils將臨時檔案流複製到新檔案裡
FileUtils.copyInputStreamToFile(tempFile.getInputStream(), new File(path,newName));
//封裝檔案資訊
info.setContentType(tempFile.getContentType());
info.setNewName(newName);
info.setNewFilePath(path);
System.out.println("儲存路徑:"+path);
info.setOriginalFilename(tempFile.getOriginalFilename());
info.setSize(tempFile.getSize());
info.setFormFieldName(tempFile.getName());
}
/*單檔案儲存,並返回新的檔案的儲存地址(包括新的檔名)*/
public FileInfo uploadFile(MultipartFile tempFile) throws Exception{
FileInfo info =null;
//如果檔案不為空
if(!tempFile.isEmpty()){
//如果上傳路徑不為空
if(null!=path){
//如果"檔名字尾陣列"不為空
if(null!=suffixs){
//字尾名
String suffix = getSuffix(tempFile);
//遍歷"檔名字尾陣列"
for(String type:suffixs){
if(type.equals(suffix)){
info = new FileInfo();
upload(tempFile,info);
}
}
}else{//如果"檔名字尾陣列"為空,則驗證"檔案型別"
//如果"檔案型別"不為空
if(null!=type){
//如果tempFile的ContentType是以"檔案型別"開頭的,則儲存該檔案
if(tempFile.getContentType().startsWith(type)){
upload(tempFile,info);
}
}
}
}
}
return info;
}
/*多檔案儲存(List<檔案資訊類>)*/
public List<FileInfo> uploadFiles(MultipartFile[] tempFiles) throws Exception{
List<FileInfo> infos =null;
//如果上傳路徑不為空
if(null!=path){
//將不為空的檔案的資訊裝入infos
infos =new ArrayList<FileInfo>();
for(MultipartFile file:tempFiles){
FileInfo info = uploadFile(file);
if(null!=info){//如果不為空,則新增到infos裡面
infos.add(info);
System.out.println("檔案原名"+file.getOriginalFilename());
}
}
}
return infos;
}
}
(5)工具測試
/springMVCdemo/WebContent/fileUpload.jsp 表單
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>fileUpload</title>
</head>
<body>
<form action="fileController/imgUpload.action" method="post" enctype="multipart/form-data">
<input type="file" name="files"/><br>
<input type="file" name="files"/><br>
<input type="submit"/>
</form>
</body>
</html>
/springMVCdemo/src/controller/fileUploadController.java 控制器
package controller;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import utils.MyFileUtil;
@Controller
@RequestMapping("/fileController")/*此處為控制器的url別名*/
public class fileUploadController {
@Resource/*該註解先根據(被Component註解的)物件名稱自動注入物件,如果名稱不對,再根據物件型別自動注入物件*/
private MyFileUtil myFileUtil;
/*注入字串,#{}為spel語言,其中fileUploadProperties,是xml配置檔案中注入properties檔案的bean id,
*path為properties檔案的其中一個key ,也可以通過下邊的set方法注入*/
@Value("#{fileUploadProperties.imgPath}")
private String imgPath;
/*獲取圖片檔名字尾陣列字串*/
@Value("#{fileUploadProperties.imgSuffixs}")
private String imgSuffixs;
/*獲取圖片的檔案型別*/
@Value("#{fileUploadProperties.imgType}")
private String imgType;
@RequestMapping("/imgUpload")
public String imgUpload(@RequestParam("files")MultipartFile[] tempFiles,ModelMap map) throws Exception{
//設定圖片的上傳路徑
myFileUtil.setPath(imgPath);
//設定檔名字尾陣列字串
myFileUtil.setSuffixs(imgSuffixs);
//設定檔案型別
myFileUtil.setType(imgType);
map.addAttribute("filesInfo", myFileUtil.uploadFiles(tempFiles));
return "forward:/fileUploadResult.jsp";
}
}
/springMVCdemo/WebContent/fileUploadResult.jsp 返回頁面顯示結果
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>fileUploadResult</title>
</head>
<body>
上傳的檔案:${requestScope.filesInfo}<br>
</body>
</html>
(6)以上的是對上傳的檔案進行嚴格的型別和字尾約束,不是指定的型別是無法上傳成功的。這裡還可以再改變一下,比如:
按照檔案型別上傳到不同的資料夾
例如:
一次性選擇了image和text和application,則一次性分別上傳到圖片資料夾、文字資料夾和應用資料夾。