[整理]WebUploader + SpringMVC 实现多文件断点续传之二 多文件断点续传

接着上一篇,实现多个大文件的断点续传。

前端JSP页面

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>


    
        文件上传
        
        
                
    
    
        
选择文件
后端Controller
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.alibaba.fastjson.JSON;


@Controller
@RequestMapping(value = "/uploadBig")
public class BigFileUploadController extends BaseController {
    /** 日志记录 */
    private static Logger logger = Logger.getLogger(BigFileUploadController.class);

    /**
     * 保存文件分片
     * @param request HttpServletRequest
     * @param response HttpServletResponse
     */
    @RequestMapping(value = "/upload",
        method = RequestMethod.POST)
    public void upload(HttpServletRequest request, HttpServletResponse response) {
        // 参数获取
        String fileName = request.getParameter("name");
        String fileMd5 = request.getParameter("fileMd5");
        String chunk = request.getParameter("chunk");
        SysUser user = getSysUser(request);
        // 临时目录
        String tempPath = FilePathUtil.getRootTempPath();
        // 转换请求对象得到文件对象
        MultipartHttpServletRequest Murequest = (MultipartHttpServletRequest) request;
        Map files = Murequest.getFileMap();
        if (null != files && !files.isEmpty()) {
            for (MultipartFile item : files.values()) {
                String tempDir = getTempDir(tempPath, user.getUserName(), fileName, fileMd5);
                // 创建临时文件夹
                File dir = new File(tempDir);
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                // 创建分片文件并保存
                File chunkFile = new File(tempDir + File.separator + chunk);
                try {
                    chunkFile.createNewFile();
                    item.transferTo(chunkFile);
                } catch (IllegalStateException e) {
                    logger.error("保存分片文件出错:" + e.getMessage());
                    e.printStackTrace();
                } catch (IOException e) {
                    logger.error("保存分片文件出错:" + e.getMessage());
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 校验分片是否已上传
     * 
     * @Title: checkChunk
     * @param request HttpServletRequest
     * @param response HttpServletResponse
     */
    @RequestMapping(value = "/check",
        method = RequestMethod.POST)
    public void checkChunk(HttpServletRequest request, HttpServletResponse response) {
        // 获取参数
        String fileName = request.getParameter("fileName");
        String fileMd5 = request.getParameter("fileMd5");
        String chunk = request.getParameter("chunk");
        String chunkSize = request.getParameter("chunkSize");
        SysUser user = getSysUser(request);
        // 临时文件
        String tempPath = FilePathUtil.getRootTempPath();
        String tempDir = getTempDir(tempPath, user.getUserName(), fileName, fileMd5);
        File chunkFile = new File(tempDir + File.separator + chunk);
        int result = 0;
        // 分片文件是否存在,尺寸是否一致
        if (chunkFile.exists() && chunkFile.length() == Integer.parseInt(chunkSize)) {
            result = 1;
        }
        returnJSONData(response, JSON.toJSONString(result));
    }

    /**
     * 合并分片成完整文件
     * 
     * @Title: mergeChunks
     * @param request HttpServletRequest
     * @param response HttpServletResponse
     */
    @SuppressWarnings("resource")
    @RequestMapping(value = "/merge",
        method = RequestMethod.POST)
    public void mergeChunks(HttpServletRequest request, HttpServletResponse response) {
        // 获取参数
        String fileName = request.getParameter("fileName");
        String fileMd5 = request.getParameter("fileMd5");
        SysUser user = getSysUser(request);
        // 获得目标文件夹
        String savePath = FilePathUtil.getFilePath();
        
        // 创建目标文件夹
        File saveDir = new File(savePath);
        if (!saveDir.exists()) {
            saveDir.mkdirs();
        }

        // 文件临时文件夹"根目录/temp/userName/文件名/MD5"
        String tempDirPath = getTempDir(FilePathUtil.getRootTempPath(), user.getUserName(), fileName, fileMd5);
        File tempDir = new File(tempDirPath);
        // 获得分片文件列表
        File[] fileArray = tempDir.listFiles(new FileFilter() {
            // 只需要文件
            @Override
            public boolean accept(File pathname) {
                if (pathname.isDirectory()) {
                    return false;
                } else {
                    return true;
                }
            }
        });
        // 转成集合进行排序后合并文件
        List fileList = new ArrayList(Arrays.asList(fileArray));
        Collections.sort(fileList, new Comparator() {
            // 按文件名升序排列
            @Override
            public int compare(File o1, File o2) {
                if (Integer.parseInt(o1.getName()) < Integer.parseInt(o2.getName())) {
                    return -1;
                } else {
                    return 1;
                }
            }
        });

        // 目标文件
        File outfile = new File(savePath + File.separator + fileName);
        try {
            outfile.createNewFile();
        } catch (IOException e) {
            logger.error("创建目标文件出错:" + e.getMessage());
            e.printStackTrace();
        }

        // 执行合并操作
        FileChannel outChannel = null;
        FileChannel inChannel;
        try {
            outChannel = new FileOutputStream(outfile).getChannel();
            for (File file : fileList) {
                inChannel = new FileInputStream(file).getChannel();
                inChannel.transferTo(0, inChannel.size(), outChannel);
                inChannel.close();
                file.delete();
            }
            outChannel.close();
        } catch (FileNotFoundException e) {
            logger.error("合并分片文件出错:" + e.getMessage());
            e.printStackTrace();
        } catch (IOException e) {
            logger.error("合并分片文件出错:" + e.getMessage());
            e.printStackTrace();
        }

        // 删除临时文件夹 根目录/temp/userName/fileName
        File tempFileDir = new File(
            FilePathUtil.getRootTempPath() + File.separator + user.getUserName() + File.separator + fileName);
        FileUtil.deleteDir(tempFileDir);
    }

    /**
     * 获得分片文件临时保存路径
     * 
     * @Title: getTempDir
     * @param tempPath 临时文件根目录
     * @param userName 用户名
     * @param fileName 文件名
     * @param fileMd5 文件MD5
     * @return String 分片临时保存路径
     */
    private String getTempDir(String tempPath, String userName, String fileName, String fileMd5) {
        StringBuilder dir = new StringBuilder(tempPath);
        dir.append(File.separator).append(userName);
        dir.append(File.separator).append(fileName);
        dir.append(File.separator).append(fileMd5);
        return dir.toString();
    }
}

你可能感兴趣的:(前端,后端)