需要使用到的maven依赖
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
需要使用到的Vo类
public class PluploadVo {
/**
* 文件原名
*/
private String name;
/**
* 用户上传资料被分解总块数
*/
private int chunks = -1;
/**
* 当前块数(从0开始计数)
*/
private int chunk = -1;
/**
* HttpServletRequest对象,不会自动赋值,需要手动传入
*/
private HttpServletRequest request;
/**
* 保存文件上传信息,不会自动赋值,需要手动传入
*/
private MultipartFile multipartFile;
}
controller 层:
@Autowired
private PluploadService pluploadService; //工具类
/**
* Plupload文件上传处理方法
*/
@RequestMapping(value = "admin/pluploadUpload")
@NotValidUser
public String upload(PluploadVo plupload, HttpServletRequest request, HttpServletResponse response, BindingResult result) {
plupload.setRequest(request);//手动传入Plupload对象HttpServletRequest属性
String path = request.getSession().getServletContext().getRealPath("");
String xingmu = "ROOT";
Integer temp = path.indexOf("ccoktv");
if (temp == null || temp < 0) {
temp = path.indexOf(xingmu);
}
/*这里切割了的目的是因为每次自己测试上传的时候都会到 Tomcat的ROOT零时目录下面,如果服务器重启或者关闭,就会使上传的
文件丢失*/
path = path.substring(0, temp) + "video";
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();//可创建多级目录,而mkdir()只能创建一级目录
}
//开始上传文件
String upload = pluploadService.upload(plupload, dir);
return Result.success(upload);
}
具体实现的service层:
import com.lormi.vo.PluploadVo;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import java.io.*;
import java.sql.Timestamp;
import java.util.Iterator;
import java.util.List;
/**
* Plupload Service模块,同Plupload实体类一样,因为要用到Spring web相关依赖,所以不将其放在Service模块
*/
@Component //将写好的类注入SpringIOC容器中让Controller自动装载
public class PluploadService {
public String upload(PluploadVo plupload, File pluploadDir) {
String fileName = "" + System.currentTimeMillis() + plupload.getName();//在服务器内生成唯一文件名
return upload(plupload, pluploadDir, fileName);
}
private String upload(PluploadVo plupload, File pluploadDir, String fileName) {
int chunks = plupload.getChunks();//用户上传文件被分隔的总块数
int nowChunk = plupload.getChunk();//当前块,从0开始
//这里Request请求类型的强制转换可能出错,配置文件中向SpringIOC容器引入multipartResolver对象即可。
MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) plupload.getRequest();
//调试发现map中只有一个键值对
MultiValueMap<String, MultipartFile> map = multipartHttpServletRequest.getMultiFileMap();
//File targetFile = new File(pluploadDir + "/" + fileName);//新建目标文件,只有被流写入时才会真正存在
if (map != null) {
try {
Iterator<String> iterator = map.keySet().iterator();
while (iterator.hasNext()) {
String key = iterator.next();
List<MultipartFile> multipartFileList = map.get(key);
for (MultipartFile multipartFile : multipartFileList) {//循环只进行一次
plupload.setMultipartFile(multipartFile);//手动向Plupload对象传入MultipartFile属性值
File targetFile = new File(pluploadDir + "/" + fileName);//新建目标文件,只有被流写入时才会真正存在
if (chunks > 1) {//用户上传资料总块数大于1,要进行合并
File tempFile = new File(pluploadDir.getPath() + "/" + multipartFile.getName());
//第一块直接从头写入,不用从末端写入
savePluploadFile(multipartFile.getInputStream(), tempFile, nowChunk == 0 ? false : true);
if (chunks - nowChunk == 1) {//全部块已经上传完毕,此时targetFile因为有被流写入而存在,要改文件名字
tempFile.renameTo(targetFile);
//每当文件上传完毕,将上传信息插入数据库
Timestamp now = new Timestamp(System.currentTimeMillis()); //是个时间参数
//youandmeService.uploadInfo(fileName, ((User) (plupload.getRequest().getSession().getAttribute("user"))).getUsername(), now);
}
} else {
//只有一块,就直接拷贝文件内容
multipartFile.transferTo(targetFile);
//每当文件上传完毕,将上传信息插入数据库
Timestamp now = new Timestamp(System.currentTimeMillis());
//youandmeService.uploadInfo(fileName, ((User) (plupload.getRequest().getSession().getAttribute("user"))).getUsername(), now);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
return "/video/" + fileName; //返回的目的是给前台一个上传之后的路径,用于直接播放
}
private void savePluploadFile(InputStream inputStream, File tempFile, boolean flag) {
OutputStream outputStream = null;
try {
if (flag == false) {
//从头写入
outputStream = new BufferedOutputStream(new FileOutputStream(tempFile));
} else {
//从末端写入
outputStream = new BufferedOutputStream(new FileOutputStream(tempFile, true));
}
byte[] bytes = new byte[1024];
int len = 0;
while ((len = (inputStream.read(bytes))) > 0) {
outputStream.write(bytes, 0, len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
outputStream.close();
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
这里唯一的确定就是上传之后的路径会直接到Tomcat的零时目录里面去,上面通过方法,重新新建了目录,以后有时间进行修改,正常的逻辑应该是到启动项目的设定目录内,
在自己的Tomcat/或者项目的Tomcat路径 D:\apache-tomcat-8.5.15\conf\Catalina\localhost 配置一个xml用来添加虚拟路径
video.xml:
<Context path="/video" reloadable="true" docBase="video" workDir="video" />
这样上面的步骤基本上已经完成 可实现多份切割上传.
applicationContext.xml的配置
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- set the max upload size100MB --> <property name="maxUploadSize"> <value>104857600</value> </property> <property name="maxInMemorySize"> <value>4096</value> </property> <property name="defaultEncoding" value="UTF-8"></property> </bean>