前面文章给出了前端页面的代码,接下来便是重点,即后台是如何接收的;在编写后台接收后,测试时发现一个问题,就是有的文件上传后会被分割为四份名字相同的文件。所以想来这个上传控件应该是将文件切分后依次上传,所以必须将这四个文件合并起来;
话不多说,上代码:
@RequestMapping(value = "file", method = RequestMethod.POST)
@ResponseBody
public String uploadFile(PlUploadEntity plupload,HttpServletRequest request, HttpServletResponse response) throws IllegalStateException, IOException {
User user = getUser(request);
plupload.setRequest(request);//手动传入Plupload对象HttpServletRequest属性
//定义上传路径
Register register = registerService.getRegisterByInnerName("RECTIFICATE_PORT_FILE_URL");
String filePath = null;
if (register != null) {
filePath = register.getRegisterValue();
if (!"\\".equals(filePath.substring(filePath.length() - 1))) {//判断末尾是否有斜杠
filePath = filePath + "\\";
}
}
File pathFile = new File(filePath);
if(!pathFile.exists() && !pathFile.isDirectory()){
pathFile.mkdirs();
}
//开始上传
String resultPath = null;
try {
resultPath = PluploadUtil.upload(plupload, pathFile);
} catch (Exception e) {
e.printStackTrace();
}
//完成上传后,在对应数据库新增一条数据
if(null != resultPath ) {
int num = resultPath.lastIndexOf("\\");
String saveName = resultPath.substring(num+1);
RectificationFiles rf = new RectificationFiles();
rf.setInstitutionId(user.getInstitutionId());
rf.setFileName(saveName);
rectificateFileService.save(2018, rf);
}
return resultPath;
}
工具类:
public class PluploadUtil {
private static final int BUF_SIZE = 2 * 1024;
/**
* 用于Plupload插件的文件上传,自动生成唯一的文件保存名
* @param plupload - 存放上传所需参数的bean
* @param dir - 保存目标文件目录
* @throws IllegalStateException
* @throws IOException
*/
public static String upload(com.tzwy.tzwy_utils.entity.PlUploadEntity plupload, File dir) throws IllegalStateException, IOException {
//生成唯一的文件名
Random ra =new Random();
int raNum = ra.nextInt(10);
int raNum2 = ra.nextInt(10);
if(raNum==0){
raNum += 1;
}
Long nowTime =System.currentTimeMillis();
String filename = nowTime + "" + (raNum*10+raNum2) + plupload.getName();
String resultMsg = upload(plupload, dir, filename);
return resultMsg;
}
/**
* 用于Plupload插件的文件上传
* @param plupload - 存放上传所需参数的bean
* @param dir - 保存目标文件目录
* @param filename - 保存的文件名
* @throws IllegalStateException
* @throws IOException
*/
public static String upload(com.tzwy.tzwy_utils.entity.PlUploadEntity plupload, File dir, String filename) throws IllegalStateException, IOException {
int chunks = plupload.getChunks(); //获取总的碎片数
int chunk = plupload.getChunk(); //获取当前碎片(从0开始计数)
String finalPath = null;
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) plupload.getRequest();
MultiValueMap<String, MultipartFile> map = multipartRequest.getMultiFileMap();
if(map != null) {
if (!dir.exists()) dir.mkdirs(); //如果目标文件夹不存在则创建新的文件夹
//事实上迭代器中只存在一个值,所以只需要返回一个值即可
Iterator<String> iter = map.keySet().iterator();
while(iter.hasNext()) {
String str = (String) iter.next();
List<MultipartFile> fileList = map.get(str);
//创建新目标文件
File targetFile = null;
for(MultipartFile multipartFile : fileList) {
//因为只存在一个值,所以最后返回的既是第一个也是最后一个值
plupload.setMultipartFile(multipartFile);
//创建新目标文件
targetFile = new File(dir.getPath() + "\\"+filename);
//当chunks>1则说明当前传的文件为一块碎片,需要合并
if (chunks > 1) {
//需要创建临时文件名,最后再更改名称
File tempFile = new File(dir.getPath() + multipartFile.getName());
//如果chunk==0,则代表第一块碎片,不需要合并
saveUploadFile(multipartFile.getInputStream(), tempFile, chunk == 0 ? false : true);
//上传并合并完成,则将临时名称更改为指定名称
if (chunks - chunk == 1) {
tempFile.renameTo(targetFile);
}
} else {
//否则直接将文件内容拷贝至新文件
multipartFile.transferTo(targetFile);
}
}
//获取已上传文件的地址以及宽、高
if(targetFile.exists()){
finalPath = dir.getPath()+ "\\"+filename;
}
}
}
return finalPath;
}
/**
* 保存上传文件,兼合并功能
*/
private static void saveUploadFile(InputStream input, File targetFile, boolean append) throws IOException {
OutputStream out = null;
try {
if (targetFile.exists() && append) {
out = new BufferedOutputStream(new FileOutputStream(targetFile, true), BUF_SIZE);
} else {
out = new BufferedOutputStream(new FileOutputStream(targetFile), BUF_SIZE);
}
byte[] buffer = new byte[BUF_SIZE];
int len = 0;
//写入文件
while ((len = input.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
} catch (IOException e) {
throw e;
} finally {
//关闭输入输出流
if (null != input) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != out) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
如此,即可完成整个过程;网上其他的都是直言碎语,此篇本人亲测可以,喜欢请点赞!
本项目中使用PlUpload下载地址:
链接:https://pan.baidu.com/s/1tVqdSyclLU1fcoZ2-_WcdQ
提取码:lg9s