1. 程式人生 > >檔案上傳優化

檔案上傳優化

一、思路:

(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,則一次性分別上傳到圖片資料夾、文字資料夾和應用資料夾。