一、思路:
(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,则一次性分别上传到图片文件夹、文本文件夹和应用文件夹。