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>Title</title>
</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 ()+"";
    }



}

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring Boot与Minio结合可以实现文件预览功能。Minio是一个开源的对象存储服务器,可以很方便地进行文件上传和下载。在Spring Boot项目中集成Minio,可以使用Minio提供的API进行文件操作,如上传、下载、删除等。 为了实现文件预览功能,首先需要在Spring Boot项目中引入Minio的依赖,并配置Minio相关的参数,包括连接地址、用户名和密码等。可以使用Minio客户端库或者直接调用Minio的RESTful API进行文件的操作。 在文件上传时,可以将文件保存到Minio服务器中,并将返回的文件访问路径保存到数据库或者其他地方。在文件预览时,可以根据文件的访问路径将文件内容展示在前端页面上,或者通过Minio提供的预览功能进行文件预览。 需要注意的是,在部署Minio服务器时,需要有两台Linux服务器,每台服务器挂载两块硬盘作为Minio节点。具体的部署过程包括分区、格式化、挂载到指定文件夹。有关具体的部署步骤和命令,可以参考相关的文档或者教程。 综上所述,通过在Spring Boot项目中集成Minio,并配置相关参数,可以实现文件预览功能。文件上传时保存文件到Minio服务器,文件预览时通过文件的访问路径展示文件内容。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [文件服务器mino实现文件存储和文件预览接口](https://download.csdn.net/download/song12345xiao/86261449)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [springboot整合minio实现文件上传下载](https://blog.csdn.net/weixin_41964243/article/details/127832843)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

缘不易

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值