利用MultipartFile实现分块上传数据

需要使用到的maven依赖


    commons-fileupload
    commons-fileupload
    1.3.1

需要使用到的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 map = multipartHttpServletRequest.getMultiFileMap();
        //File targetFile = new File(pluploadDir + "/" + fileName);//新建目标文件,只有被流写入时才会真正存在
        if (map != null) {
            try {
                Iterator iterator = map.keySet().iterator();
                while (iterator.hasNext()) {
                    String key = iterator.next();
                    List 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:

这样上面的步骤基本上已经完成 可实现多份切割上传.

applicationContext.xml的配置


    
    
        104857600
    
    
        4096
    
    

 

你可能感兴趣的:(工作随笔)