SpringBoot实现文件上传与预览

上代码:

请求方式:Content-Type multipart/form-data;

单文件上传

控制层

	@PostMapping("/uploadFile")
	public ResponseData<String> uploadFile(@RequestParam("file") MultipartFile file,HttpServletRequest request) throws IOException {
		return fileService.uploadFile(file,request);
	}

实现层


	@Override
	public ResponseData<String> uploadFile(MultipartFile file, HttpServletRequest request) throws IOException {

		String oldFileName = file.getOriginalFilename();
		String exname = null;
		if (oldFileName != null) {
			exname = oldFileName.substring(oldFileName.lastIndexOf("."));
			String newFileName = IdUtil.createId() + exname;
			String path = upload + "/" + newFileName;
			File fileUploadPath = new File(path);
			if (!fileUploadPath.exists()) {
				fileUploadPath.createNewFile();
			}
			try {

				file.transferTo(fileUploadPath);
				String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/file/showFile?name=" + newFileName;
				return ResponseData.success("上传成功", basePath);
			} catch (IOException e) {
				e.printStackTrace();
			}

		}
		return ResponseData.failure("上传失败");

	}

多文件上传

控制层


	@PostMapping("/uploadAnyFile")
	public ResponseData<List<String>> uploadAnyFile(HttpServletRequest request) throws IOException, ServletException {
		return fileService.uploadAnyFile(request);
	}

实现层


	@Override
	public ResponseData<List<String>> uploadAnyFile(HttpServletRequest request) throws IOException, ServletException {
		Collection<Part> parts = request.getParts();
		List<String> list = new ArrayList<>();

		parts.forEach(part -> {
			//String header = part.getHeader("content-disposition");
			String fileName = part.getSubmittedFileName();
			String exname = fileName.substring(fileName.lastIndexOf("."));
			InputStream inputStream = null;
			OutputStream outputStream = null;

			try {
				String name = IdUtil.createId() + exname;
				inputStream = part.getInputStream();
				File file = new File(upload + "/" + name);
				if (!file.exists()) {
					file.createNewFile();
				}
				outputStream = new FileOutputStream(file);
				int i = FileCopyUtils.copy(inputStream, outputStream);
				long size = part.getSize();
				if (i == size) {
					String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/file/showFile?name=" + name;
					list.add(basePath);
				} else {
					file.delete();
				}
			} catch (IOException e) {
				e.printStackTrace();

			}
		});
		if (parts.size() == list.size()) {
			return ResponseData.success("文件上传成功", list);
		}
		return ResponseData.failure("文件上传失败");
	}

文件预览

控制层

@GetMapping("/showFile")
	public void showFile(HttpServletRequest request, HttpServletResponse response) {
		fileService.showFile(request,response);
	}

实现层


	@Override
	public void showFile(HttpServletRequest request, HttpServletResponse response) {
		String name = request.getParameter("name");
		String path = upload + "/" + name;
		try (FileImageInputStream input = new FileImageInputStream(new File(path));
			 OutputStream out = response.getOutputStream();
			 ByteArrayOutputStream output = new ByteArrayOutputStream()) {
			byte[] buf = new byte[1024];
			int len = -1;
			while ((len = input.read(buf)) != -1) {
				output.write(buf, 0, len);
			}
			byte[] data = output.toByteArray();
			out.write(data);
			out.flush();
		} catch (IOException ex) {
			ex.printStackTrace();
			log.error("文件预览发生异常:{}", ex.getMessage());
		}

	}

大文件分片,断点续传

Hmlt

DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
<div>
    <input type="file" id="pick" value="选择文件"/>
    <input type="submit" id="submit" value="上传文件"/>
div>
<script th:src="@{/js/jquery.min.js}">script>
<script>

    $(function () {
        let file;
        let elementById = window.document.getElementById("pick");
        elementById.addEventListener('change', function () {
            //传递参数
            file = elementById.files[0]

        })

        let submit = window.document.getElementById("submit");
        submit.addEventListener('click', function () {
            let maxSize = 2 * 1024 * 1024;// 默认分片大小 2M
            let index = 0;// 默认从第0片开始
            let size = file.size;
            let ceil = Math.ceil(size / maxSize);// 计算总分片
            let exname = file.name.substr(file.name.lastIndexOf("."))
            let chunks = [];

            if (ceil > 50) {
                //防止总切片数过多
                ceil = 50
                maxSize = size / ceil;
            }
            while (index < ceil) {
                chunks.push({
                    file: file.slice(index * maxSize, (index + 1) * maxSize),
                    filename: "chunk_" + index + exname,
                    chunk: index
                })
                index++;
            }
            var i = 1;
            chunks.forEach(f => {
                let formdata = new FormData();
                formdata.append("file", f.file);
                formdata.append("filename", f.filename)
                $.ajax({
                    url: "/file/uploadBigFile",  //上传地址
                    headers: {
                        "Authorization": "Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImlkIjpudWxsLCJleHAiOjE2NTU4Nzc2NjMsImlhdCI6MTY1NTI3Mjg2MywidXNlcm5hbWUiOiJhZG1pbiJ9.qI7tGsvZ4rVcZXni1X20-ouaZOr5veItZdTc63K6ZwI"
                    },
                    type: "post",
                    data: formdata,  // 传入实例化的formData对象,此对象包含了要上传的文件
                    contentType: false, // 在请求服务器的时候,数据有非字符串格式的内容(文件是二进制)
                    processData: false,  // formData对象不需要转换成参数字符串,
                    success: function (data) {
                        if (i === ceil) {
                            console.log("合并文件")
                            $.ajax({
                                url: "/file/mergeBigFile",  //上传地址
                                headers: {
                                    "Authorization": "Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImlkIjpudWxsLCJleHAiOjE2NTU4Nzc2NjMsImlhdCI6MTY1NTI3Mjg2MywidXNlcm5hbWUiOiJhZG1pbiJ9.qI7tGsvZ4rVcZXni1X20-ouaZOr5veItZdTc63K6ZwI"
                                },
                                type: "get",
                                data: {
                                    "chunks": ceil,
                                    "exname": exname
                                },  // 传入实例化的formData对象,此对象包含了要上传的文件
                                success: function (data) {
                                    console.log(data)
                                }
                            })
                        }
                        i++;

                    }
                })
            })


        })


    })


script>
body>
html>

控制层


	/**
	 * 大文件分片,断点续传
 	 */

	@PostMapping("/uploadBigFile")
	public ResponseData<String> uploadBigFile(@RequestParam("file") MultipartFile file,@RequestParam("filename") String filename) {
		return fileService.uploadBigFile(file,filename);
	}


	/**
	 * 合并文件
	 */

	@GetMapping("/mergeBigFile")
	public ResponseData<String> mergeBigFile(@RequestParam("chunks")Integer chunks,String exname) {
		return fileService.mergeBigFile(chunks,exname);
	}

实现层


	@Override
	public ResponseData<String> uploadBigFile(MultipartFile file, String filename) {

		try {
			String path = upload + "/" + filename;
			File fileUploadPath = new File(path);
			if (!fileUploadPath.exists()) {
				fileUploadPath.createNewFile();
				file.transferTo(fileUploadPath);
			}

			return ResponseData.success("上传成功", "");
		} catch (IOException e) {
			e.printStackTrace();
		}

		return ResponseData.failure("上传文件失败");
	}
	/**
	 * 文件合并
	 */
	@Override
	public ResponseData<String> mergeBigFile(Integer chunks,String exname) {

			RandomAccessFile raf = null;
			try {
				//申明随机读取文件RandomAccessFile
				File file = new File(upload+"/"+IdUtil.createId()+exname);
				if (!file.exists()) {
					file.createNewFile();
				}
				raf = new RandomAccessFile(file, "rw");
				//开始合并文件,对应切片的二进制文件
				for (int i = 0; i < chunks; i++) {
					File file1 = new File(upload + "/chunk_" + i + exname);
					//读取切片文件
					RandomAccessFile reader = new RandomAccessFile(file1, "r");
					byte[] b = new byte[1024];
					int n = 0;
					//先读后写
					while ((n = reader.read(b)) != -1) {
						raf.write(b, 0, n);
					}
					reader.close();
					if (file1.exists()) {
						file1.delete();
					}
				}

			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				try {
					raf.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

		return ResponseData.success("文件上传成功");
	}

IdUtil

@Component
public class IdUtil {
   private static Snowflake snowflake=null;
    public static String createId () {
        if(StrUtil.isBlankIfStr (snowflake)){
            snowflake = cn.hutool.core.util.IdUtil.getSnowflake (1, 1);
        }
        return snowflake.nextId ()+"";
    }



}

你可能感兴趣的:(springboot,spring,boot,java,spring)