当前位置:   article > 正文

【Java】java实现文件上传和下载(上传到指定路径/数据库/minio)_java 上传文件

java 上传文件

目录

上传到指定路径

一、代码层级结构

二、文件上传接口

三、使用postman进行测试;

MultipartFile接收前端传递的文件:127.0.0.1:8082/path/uploadFile

part接收前端传递的文件:127.0.0.1:8082/path/uploadFileByRequest

四、上传文件大小设置

五、文件下载接口

六、使用postman进行测试

上传至数据库

一、代码层级结构

二、文件上传接口

三、文件下载接口

四、使用postman进行测试

上传至Minio

一、代码层级结构

二、文件上传/下载接口

MinioUtils

        InitConfig

        MinioConfig

三、使用postman进行测试


        业务分析:实际开发过程中,我们经常对文件的上传和下载的功能实现,所以这也是一个程序员应该掌握的基本开发能力。所以下面我给大家分享一下文件上传和下载的三种方式,分别将文件上传到指定路径下/本地数据库/minio当中。

       所有代码都以上传至压缩包资源,可以自行免费进行下载测试;

所有application.yml为:

  1. # MyBatis
  2. mybatis:
  3. mapper-locations: classpath*:mapper/*.xml
  4. server:
  5. port: 8888
  6. spring:
  7. application:
  8. name: user-service
  9. datasource:
  10. url: jdbc:mysql://127.0.0.1:3306/xxx
  11. username: root
  12. password: xxx
  13. driver-class-name: com.mysql.cj.jdbc.Driver
  14. # Redis
  15. data:
  16. redis:
  17. port: 6379
  18. username:
  19. password:
  20. host: 127.0.0.1
  21. # Minio
  22. minio:
  23. access-key: "username"
  24. secret-key: "password"
  25. end-point: "http://127.0.0.1:9000/"
  26. bucket: "playedu"
  27. domain: "http://127.0.0.1:9000/"

上传到指定路径

一、代码层级结构

        

二、文件上传接口

  1. /**
  2. * 上传到指定路径下
  3. */
  4. @RestController
  5. @Slf4j
  6. @RequestMapping("/path")
  7. public class UploadController {
  8. @Autowired
  9. private ResourceLoader resourceLoader;
  10. private BufferedOutputStream bufferedOutputStream = null;
  11. /**
  12. * form-data 类型
  13. * form-data 类型即常用的表单提交
  14. * 两种处理参数的方式
  15. * <p>
  16. * MultipartFile 类接受前台传过来的文件
  17. * part 接收字节流
  18. */
  19. @PostMapping("/uploadFile")
  20. public String uploadFile(@RequestParam("name") String name, @RequestPart("file1") MultipartFile file1, @RequestPart("file2") MultipartFile[] file2) throws IOException, ServletException {
  21. // 获取项目部署路径
  22. /* String appPath = request.getServletContext().getRealPath("/");
  23. // 构建上传文件的目录路径
  24. String path = appPath + "static/upload/";*/
  25. //绝对路劲
  26. // String path = "D:\\Users\\MXIN\\IdeaProjects\\springboot-uploadanddownload\\src\\main\\resources\\static\\";
  27. //相对路径
  28. String path = "src/main/resources/static/";
  29. //前端传递多个file(只对file2进行处理)
  30. for (MultipartFile multipartFile : file2) {
  31. // 使用 MultipartFile 字节流保存文件
  32. fileUtil(multipartFile, String.valueOf(path));
  33. }
  34. fileUtil(file1, String.valueOf(path));
  35. return "success";
  36. }
  37. /**
  38. * part 接收字节流
  39. */
  40. @PostMapping("/uploadFileByRequest")
  41. public String uploadFileByRequest(HttpServletRequest request) throws IOException, ServletException {
  42. // 获取项目部署路径
  43. /* String appPath = request.getServletContext().getRealPath("/");
  44. // 构建上传文件的目录路径
  45. String path = appPath + "static/upload/";*/
  46. //绝对路劲
  47. String path = "D:\\Users\\MXIN\\IdeaProjects\\springboot-uploadanddownload\\src\\main\\resources\\static\\";
  48. // 使用 Part 接收文件字节流
  49. // Part file1 = request.getPart("file1");
  50. // file1.write(path + file1.getSubmittedFileName());
  51. // request.getParts() 获取的是全部参数(name,age,file1,file2),包括文件参数和非文件参数
  52. for (Part part : request.getParts()) {
  53. // 获取文件类型
  54. String contentType = part.getContentType();
  55. // 获取文件大小
  56. long size = part.getSize();
  57. // 获取文件名
  58. String submittedFileName = part.getSubmittedFileName();
  59. if (part.getContentType() != null) {
  60. //如果是文件会进行写入
  61. part.write(path + part.getSubmittedFileName());
  62. } else {
  63. // 如果是参数会获取参数(根据实际需求对参数进行处理)
  64. // 获取参数名
  65. String name1 = part.getName();
  66. }
  67. }
  68. return "success";
  69. }
  70. public String fileUtil(MultipartFile file, String path) {
  71. if (!file.isEmpty()) {
  72. try {
  73. byte[] bytes = file.getBytes();
  74. bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(
  75. new File(path + file.getOriginalFilename())));
  76. bufferedOutputStream.write(bytes);
  77. bufferedOutputStream.close();
  78. return file.getOriginalFilename() + "上传成功";
  79. } catch (Exception e) {
  80. return file.getOriginalFilename() + "上传失败,错误信息为:" + e;
  81. }
  82. } else {
  83. return "上传得文件为空";
  84. }
  85. }
  86. }

三、使用postman进行测试;

MultipartFile接收前端传递的文件:127.0.0.1:8082/path/uploadFile

测试结果

part接收前端传递的文件:127.0.0.1:8082/path/uploadFileByRequest

测试结果

四、上传文件大小设置

        由于springboot默认上传文件大小为1M,单个请求最大为10M,当文件超过1M会报错。所以可以通过配置文件限制文件上传大小。

上传大于1M报错信息为:

Resolved [org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size exceeded]

所以修改配置文件(根据自己实际开发需求进行修改):

上述简单的介绍了文件上传到指定路径下的方法,下面来简单介绍一下文件下载是如何实现的。

五、文件下载接口

  1. /**
  2. * 下载指定路径下的文件
  3. * */
  4. @RestController
  5. @Slf4j
  6. @RequestMapping("/path")
  7. public class DownloadController {
  8. /**
  9. * 文件下载 isOnline默认为false
  10. */
  11. @GetMapping("/download")
  12. public void download(String fileName, HttpServletResponse response, boolean isOnLine) throws IOException {
  13. // 路径可以指定当前项目相对路径
  14. File file = new File("D:\\Users\\Mixi\\IdeaProjects\\springboot-uploadanddownload\\src\\main\\resources\\static\\" + fileName);
  15. if (file.exists()) {
  16. FileInputStream fileInputStream = new FileInputStream(file);
  17. ServletOutputStream outputStream = response.getOutputStream();
  18. // 获取文件扩展名
  19. String extension = fileName.substring(fileName.lastIndexOf(".") + 1);
  20. if (!isOnLine) {
  21. // 根据文件扩展名设置Content-Type
  22. String contentType = getContentType(extension);
  23. response.setContentType(contentType);
  24. // 如果文件名为中文需要设置编码
  25. response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName, "utf8"));
  26. // 返回前端文件名需要添加
  27. response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
  28. }
  29. byte[] bytes = new byte[1024];
  30. int len;
  31. while ((len = fileInputStream.read(bytes)) != -1) {
  32. outputStream.write(bytes, 0, len);
  33. }
  34. }
  35. }
  36. // 根据文件扩展名获取Content-Type
  37. private String getContentType(String extension) {
  38. if ("jpg".equalsIgnoreCase(extension) || "jpeg".equalsIgnoreCase(extension)) {
  39. return "image/jpeg";
  40. } else if ("png".equalsIgnoreCase(extension)) {
  41. return "image/png";
  42. } else if ("gif".equalsIgnoreCase(extension)) {
  43. return "image/gif";
  44. } else if ("txt".equalsIgnoreCase(extension)) {
  45. return "text/plain";
  46. } else if ("pdf".equalsIgnoreCase(extension)) {
  47. return "application/pdf";
  48. } else if ("doc".equalsIgnoreCase(extension) || "docx".equalsIgnoreCase(extension)) {
  49. return "application/msword";
  50. } else if ("xls".equalsIgnoreCase(extension) || "xlsx".equalsIgnoreCase(extension)) {
  51. return "application/vnd.ms-excel";
  52. } else if ("ppt".equalsIgnoreCase(extension) || "pptx".equalsIgnoreCase(extension)) {
  53. return "application/vnd.ms-powerpoint";
  54. } else if ("zip".equalsIgnoreCase(extension)) {
  55. return "application/zip";
  56. } else if ("tar".equalsIgnoreCase(extension)) {
  57. return "application/x-tar";
  58. } else if ("rar".equalsIgnoreCase(extension)) {
  59. return "application/x-rar-compressed";
  60. } else if ("gz".equalsIgnoreCase(extension)) {
  61. return "application/gzip";
  62. } else {
  63. return "application/octet-stream";
  64. }
  65. }
  66. }

六、使用postman进行测试

isOnlie为true和false决定了是否在浏览器上在线查看。

上传至数据库

这种业务需求就是用于项目开发过程中,文件上传下载的功能用的很少,避免搭建部署文件存储的服务器,简化了部署和管理,节约成本资源。

一、代码层级结构

二、文件上传接口

UploadToDBController:

  1. /**
  2. * 上传到数据库
  3. * */
  4. @RestController
  5. @Slf4j
  6. @RequestMapping("/db")
  7. public class UploadToDBController {
  8. @Autowired
  9. private FilesService filesService;
  10. @PostMapping("/uploadFile")
  11. public Files inputFile(@RequestParam("file") MultipartFile file) {
  12. Files files = new Files();
  13. if (null != file) {
  14. String name = file.getOriginalFilename();
  15. byte[] bytes;
  16. try {
  17. bytes = file.getBytes();
  18. } catch (IOException e) {
  19. throw new RuntimeException(e);
  20. }
  21. files.setName(name);
  22. files.setFile(bytes);
  23. filesService.save(files);
  24. }
  25. return files;
  26. }
  27. }

FilesServiceImpl:

  1. @Override
  2. public void save(Files files) {
  3. filesMapper.insert(files);
  4. }

简单代码的增删改查我就不写了哈。

三、文件下载接口

DownloadFromDBController:

  1. /**
  2. * 从数据库下载
  3. */
  4. @RestController
  5. @Slf4j
  6. @RequestMapping("/db")
  7. public class DownloadFromDBController {
  8. @Autowired
  9. private FilesService filesService;
  10. @GetMapping("/download/{id}")
  11. public void download(HttpServletResponse response, @PathVariable("id") Integer id) {
  12. filesService.download(response,id);
  13. }
  14. }

FilesServiceImpl:

  1. @Override
  2. public HttpServletResponse download(HttpServletResponse response, Integer id) {
  3. try {
  4. byte[] buf;
  5. Files byId = filesMapper.selectById(id);
  6. if (byId == null) {
  7. return response;
  8. }
  9. buf = byId.getFile();
  10. String suffix = FileToMultipartFile.getSuffix(byId.getName());
  11. String contentType = "";
  12. switch (Objects.requireNonNull(FileTypeEnum.getEnum(suffix))) {
  13. case DOC:
  14. contentType = "application/msword";
  15. break;
  16. case DOCX:
  17. contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
  18. break;
  19. case PDF:
  20. contentType = "application/powerpoint";
  21. break;
  22. case JPE:
  23. case JPG:
  24. case JPEG:
  25. contentType = "image/jpeg";
  26. break;
  27. case PNG:
  28. contentType = "image/png";
  29. break;
  30. case ZIP:
  31. contentType = "application/zip";
  32. break;
  33. case TAR:
  34. contentType = "application/x-tar";
  35. break;
  36. case GZ:
  37. contentType = "application/x-gzip";
  38. break;
  39. case XLS:
  40. contentType = "application/vnd.ms-excel";
  41. break;
  42. case XLSX:
  43. contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
  44. break;
  45. case PPT:
  46. contentType = "application/vnd.ms-powerpoint";
  47. break;
  48. case PPTX:
  49. contentType = "application/vnd.openxmlformats-officedocument.presentationml.presentation";
  50. break;
  51. }
  52. // 清空
  53. response.reset();
  54. String encodedFileName = URLEncoder.encode(byId.getName().replaceAll(" ", "+"), "UTF-8");
  55. // 设置header
  56. response.addHeader("Content-Disposition", "attachment;filename=" + encodedFileName);
  57. // response.addHeader("Content-Length", "" + byId.getFileNo());
  58. response.setCharacterEncoding("UTF-8");
  59. response.setContentType(contentType);
  60. response.getOutputStream().write(buf);
  61. // 强制输出,不然会留在内存里丢失掉
  62. response.getOutputStream().flush();
  63. return response;
  64. } catch (Exception e) {
  65. throw new RuntimeException(e);
  66. }
  67. }

四、使用postman进行测试

文件上传:

测试结果数据库:

文件下载:

 测试结果:

上传至Minio

        首先要在本地或者服务器上部署minio并启动才可以进行文件的上传和下载,还未安装minio的可以参考一下这篇文章:【Docker】手把手教你在windows使用Docker安装Minio[详细教程]_minio windows-CSDN博客

一、代码层级结构

二、文件上传/下载接口

  1. /**
  2. * 文件上传、下载、删除、获取文件信息、获取文件url接口
  3. * */
  4. @Slf4j
  5. @RestController
  6. @RequestMapping("/oss")
  7. public class MinioController {
  8. @Autowired
  9. private MinioUtils minioUtils;
  10. @Autowired
  11. private MinioConfig minioConfig;
  12. /**
  13. * 文件上传
  14. *
  15. * @param file
  16. */
  17. @PostMapping("/upload")
  18. public String upload(@RequestParam("file") MultipartFile file) {
  19. try {
  20. //文件名
  21. String fileName = file.getOriginalFilename();
  22. String newFileName = System.currentTimeMillis() + "." + StringUtils.substringAfterLast(fileName, ".");
  23. //类型
  24. String contentType = file.getContentType();
  25. minioUtils.uploadFile(minioConfig.getBucketName(), file, newFileName, contentType);
  26. return "上传成功,文件名:" + newFileName;
  27. } catch (Exception e) {
  28. e.printStackTrace();
  29. return "上传失败";
  30. }
  31. }
  32. /**
  33. * 删除
  34. *
  35. * @param fileName
  36. */
  37. @DeleteMapping("/")
  38. public void delete(@RequestParam("fileName") String fileName) {
  39. minioUtils.removeFile(minioConfig.getBucketName(), fileName);
  40. }
  41. /**
  42. * 获取文件信息
  43. *
  44. * @param fileName
  45. * @return
  46. */
  47. @GetMapping("/info")
  48. public String getFileStatusInfo(@RequestParam("fileName") String fileName) {
  49. return minioUtils.getFileStatusInfo(minioConfig.getBucketName(), fileName);
  50. }
  51. /**
  52. * 获取文件外链
  53. *
  54. * @param fileName
  55. * @return
  56. */
  57. @GetMapping("/url")
  58. public String getPresignedObjectUrl(@RequestParam("fileName") String fileName) {
  59. return minioUtils.getPresignedObjectUrl(minioConfig.getBucketName(), fileName);
  60. }
  61. /**
  62. * 文件下载
  63. *
  64. * @param fileName
  65. * @param response
  66. */
  67. @GetMapping("/download")
  68. public void download(@RequestParam("fileName") String fileName, HttpServletResponse response) {
  69. try {
  70. InputStream fileInputStream = minioUtils.getObject(minioConfig.getBucketName(), fileName);
  71. response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
  72. response.setContentType("application/force-download");
  73. response.setCharacterEncoding("UTF-8");
  74. IOUtils.copy(fileInputStream, response.getOutputStream());
  75. } catch (Exception e) {
  76. log.error("下载失败");
  77. }
  78. }
  79. }

MinioUtils

  1. @Slf4j
  2. @Component
  3. public class MinioUtils {
  4. @Autowired
  5. private MinioClient minioClient;
  6. /**
  7. * 启动SpringBoot容器的时候初始化Bucket
  8. * 如果没有Bucket则创建
  9. *
  10. * @param bucketName
  11. */
  12. public void createBucket(String bucketName) {
  13. try {
  14. if (!bucketExists(bucketName)) {
  15. minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
  16. log.info("创建bucketName = {}完成!", bucketName);
  17. return;
  18. }
  19. log.info("bucketName = {}已存在!策略为:{}", bucketName, getBucketPolicy(bucketName));
  20. } catch (Exception e) {
  21. log.error("创建bucketName = {}异常!e = {}", bucketName, e);
  22. }
  23. }
  24. /**
  25. * 判断Bucket是否存在,true:存在,false:不存在
  26. *
  27. * @param bucketName
  28. * @return
  29. */
  30. @SneakyThrows
  31. public boolean bucketExists(String bucketName) {
  32. return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
  33. }
  34. /**
  35. * 获得Bucket的策略
  36. *
  37. * @param bucketName
  38. * @return
  39. */
  40. @SneakyThrows
  41. public String getBucketPolicy(String bucketName) {
  42. return minioClient.getBucketPolicy(GetBucketPolicyArgs.builder().bucket(bucketName).build());
  43. }
  44. /**
  45. * 获得所有Bucket列表
  46. *
  47. * @return
  48. */
  49. @SneakyThrows
  50. public List<Bucket> getAllBuckets() {
  51. return minioClient.listBuckets();
  52. }
  53. /**
  54. * 根据bucketName获取其相关信息
  55. *
  56. * @param bucketName
  57. * @return
  58. */
  59. @SneakyThrows(Exception.class)
  60. public Optional<Bucket> getBucket(String bucketName) {
  61. return getAllBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst();
  62. }
  63. /**
  64. * 根据bucketName删除Bucket,true:删除成功; false:删除失败,文件或已不存在
  65. *
  66. * @param bucketName
  67. * @throws Exception
  68. */
  69. @SneakyThrows(Exception.class)
  70. public void removeBucket(String bucketName) {
  71. minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
  72. }
  73. /**
  74. * 判断文件是否存在
  75. *
  76. * @param bucketName
  77. * @param objectName
  78. * @return
  79. */
  80. public boolean isObjectExist(String bucketName, String objectName) {
  81. boolean exist = true;
  82. try {
  83. minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build());
  84. } catch (Exception e) {
  85. log.error("[Minio工具类]>>>> 判断文件是否存在, 异常:", e);
  86. exist = false;
  87. }
  88. return exist;
  89. }
  90. /**
  91. * 判断文件夹是否存在
  92. *
  93. * @param bucketName
  94. * @param objectName
  95. * @return
  96. */
  97. public boolean isFolderExist(String bucketName, String objectName) {
  98. boolean exist = false;
  99. try {
  100. Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).prefix(objectName).recursive(false).build());
  101. for (Result<Item> result : results) {
  102. Item item = result.get();
  103. if (item.isDir() && objectName.equals(item.objectName())) {
  104. exist = true;
  105. }
  106. }
  107. } catch (Exception e) {
  108. log.error("[Minio工具类]>>>> 判断文件夹是否存在,异常:", e);
  109. exist = false;
  110. }
  111. return exist;
  112. }
  113. /**
  114. * 根据文件前置查询文件
  115. *
  116. * @param bucketName 存储桶
  117. * @param prefix 前缀
  118. * @param recursive 是否使用递归查询
  119. * @return MinioItem 列表
  120. */
  121. @SneakyThrows(Exception.class)
  122. public List<Item> getAllObjectsByPrefix(String bucketName, String prefix, boolean recursive) {
  123. List<Item> list = new ArrayList<>();
  124. Iterable<Result<Item>> objectsIterator = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build());
  125. if (objectsIterator != null) {
  126. for (Result<Item> o : objectsIterator) {
  127. Item item = o.get();
  128. list.add(item);
  129. }
  130. }
  131. return list;
  132. }
  133. /**
  134. * 获取文件流
  135. *
  136. * @param bucketName 存储桶
  137. * @param objectName 文件名
  138. * @return 二进制流
  139. */
  140. @SneakyThrows(Exception.class)
  141. public InputStream getObject(String bucketName, String objectName) {
  142. return minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build());
  143. }
  144. /**
  145. * 断点下载
  146. *
  147. * @param bucketName 存储桶
  148. * @param objectName 文件名称
  149. * @param offset 起始字节的位置
  150. * @param length 要读取的长度
  151. * @return 二进制流
  152. */
  153. @SneakyThrows(Exception.class)
  154. public InputStream getObject(String bucketName, String objectName, long offset, long length) {
  155. return minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).offset(offset).length(length).build());
  156. }
  157. /**
  158. * 获取路径下文件列表
  159. *
  160. * @param bucketName 存储桶
  161. * @param prefix 文件名称
  162. * @param recursive 是否递归查找,false:模拟文件夹结构查找
  163. * @return 二进制流
  164. */
  165. public Iterable<Result<Item>> listObjects(String bucketName, String prefix, boolean recursive) {
  166. return minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build());
  167. }
  168. /**
  169. * 使用MultipartFile进行文件上传
  170. *
  171. * @param bucketName 存储桶
  172. * @param file 文件名
  173. * @param objectName 对象名
  174. * @param contentType 类型
  175. * @return
  176. */
  177. @SneakyThrows(Exception.class)
  178. public ObjectWriteResponse uploadFile(String bucketName, MultipartFile file, String objectName, String contentType) {
  179. InputStream inputStream = file.getInputStream();
  180. return minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).contentType(contentType).stream(inputStream, inputStream.available(), -1).build());
  181. }
  182. /**
  183. * 图片上传
  184. *
  185. * @param bucketName
  186. * @param imageBase64
  187. * @param imageName
  188. * @return
  189. */
  190. public ObjectWriteResponse uploadImage(String bucketName, String imageBase64, String imageName) {
  191. if (!StringUtils.isEmpty(imageBase64)) {
  192. InputStream in = base64ToInputStream(imageBase64);
  193. String newName = System.currentTimeMillis() + "_" + imageName + ".jpg";
  194. String year = String.valueOf(new Date().getYear());
  195. String month = String.valueOf(new Date().getMonth());
  196. return uploadFile(bucketName, year + "/" + month + "/" + newName, in);
  197. }
  198. return null;
  199. }
  200. public static InputStream base64ToInputStream(String base64) {
  201. ByteArrayInputStream stream = null;
  202. try {
  203. byte[] bytes = Base64.getEncoder().encode(base64.trim().getBytes());
  204. stream = new ByteArrayInputStream(bytes);
  205. } catch (Exception e) {
  206. e.printStackTrace();
  207. }
  208. return stream;
  209. }
  210. /**
  211. * 上传本地文件
  212. *
  213. * @param bucketName 存储桶
  214. * @param objectName 对象名称
  215. * @param fileName 本地文件路径
  216. * @return
  217. */
  218. @SneakyThrows(Exception.class)
  219. public ObjectWriteResponse uploadFile(String bucketName, String objectName, String fileName) {
  220. return minioClient.uploadObject(UploadObjectArgs.builder().bucket(bucketName).object(objectName).filename(fileName).build());
  221. }
  222. /**
  223. * 通过流上传文件
  224. *
  225. * @param bucketName 存储桶
  226. * @param objectName 文件对象
  227. * @param inputStream 文件流
  228. * @return
  229. */
  230. @SneakyThrows(Exception.class)
  231. public ObjectWriteResponse uploadFile(String bucketName, String objectName, InputStream inputStream) {
  232. return minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(inputStream, inputStream.available(), -1).build());
  233. }
  234. /**
  235. * 创建文件夹或目录
  236. *
  237. * @param bucketName 存储桶
  238. * @param objectName 目录路径
  239. * @return
  240. */
  241. @SneakyThrows(Exception.class)
  242. public ObjectWriteResponse createDir(String bucketName, String objectName) {
  243. return minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(new ByteArrayInputStream(new byte[]{}), 0, -1).build());
  244. }
  245. /**
  246. * 获取文件信息, 如果抛出异常则说明文件不存在
  247. *
  248. * @param bucketName 存储桶
  249. * @param objectName 文件名称
  250. * @return
  251. */
  252. @SneakyThrows(Exception.class)
  253. public String getFileStatusInfo(String bucketName, String objectName) {
  254. return minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build()).toString();
  255. }
  256. /**
  257. * 拷贝文件
  258. *
  259. * @param bucketName 存储桶
  260. * @param objectName 文件名
  261. * @param srcBucketName 目标存储桶
  262. * @param srcObjectName 目标文件名
  263. */
  264. @SneakyThrows(Exception.class)
  265. public ObjectWriteResponse copyFile(String bucketName, String objectName, String srcBucketName, String srcObjectName) {
  266. return minioClient.copyObject(CopyObjectArgs.builder().source(CopySource.builder().bucket(bucketName).object(objectName).build()).bucket(srcBucketName).object(srcObjectName).build());
  267. }
  268. /**
  269. * 删除文件
  270. *
  271. * @param bucketName 存储桶
  272. * @param objectName 文件名称
  273. */
  274. @SneakyThrows(Exception.class)
  275. public void removeFile(String bucketName, String objectName) {
  276. minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build());
  277. }
  278. /**
  279. * 批量删除文件
  280. *
  281. * @param bucketName 存储桶
  282. * @param keys 需要删除的文件列表
  283. * @return
  284. */
  285. public void removeFiles(String bucketName, List<String> keys) {
  286. List<DeleteObject> objects = new LinkedList<>();
  287. keys.forEach(s -> {
  288. objects.add(new DeleteObject(s));
  289. try {
  290. removeFile(bucketName, s);
  291. } catch (Exception e) {
  292. log.error("[Minio工具类]>>>> 批量删除文件,异常:", e);
  293. }
  294. });
  295. }
  296. /**
  297. * 获取文件外链
  298. *
  299. * @param bucketName 存储桶
  300. * @param objectName 文件名
  301. * @param expires 过期时间 <=7 秒 (外链有效时间(单位:秒))
  302. * @return url
  303. */
  304. @SneakyThrows(Exception.class)
  305. public String getPresignedObjectUrl(String bucketName, String objectName, Integer expires) {
  306. GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder().expiry(expires).bucket(bucketName).object(objectName).build();
  307. return minioClient.getPresignedObjectUrl(args);
  308. }
  309. /**
  310. * 获得文件外链
  311. *
  312. * @param bucketName
  313. * @param objectName
  314. * @return url
  315. */
  316. @SneakyThrows(Exception.class)
  317. public String getPresignedObjectUrl(String bucketName, String objectName) {
  318. GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(objectName).method(Method.GET).build();
  319. return minioClient.getPresignedObjectUrl(args);
  320. }
  321. /**
  322. * 将URLDecoder编码转成UTF8
  323. *
  324. * @param str
  325. * @return
  326. * @throws UnsupportedEncodingException
  327. */
  328. public String getUtf8ByURLDecoder(String str) throws UnsupportedEncodingException {
  329. String url = str.replaceAll("%(?![0-9a-fA-F]{2})", "%25");
  330. return URLDecoder.decode(url, "UTF-8");
  331. }
  332. }

        InitConfig

  1. @Component
  2. @Slf4j
  3. public class InitConfig implements InitializingBean {
  4. @Autowired
  5. private MinioUtils minioUtils;
  6. @Autowired
  7. private MinioConfig minioConfig;
  8. @Override
  9. public void afterPropertiesSet() throws Exception {
  10. // 项目启动创建Bucket,不存在则进行创建
  11. minioUtils.createBucket(minioConfig.getBucketName());
  12. }
  13. }

        MinioConfig

  1. import io.minio.MinioClient;
  2. import lombok.Data;
  3. import org.springframework.beans.factory.annotation.Value;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.Configuration;
  6. @Data
  7. @Configuration
  8. public class MinioConfig {
  9. /**
  10. * 访问地址
  11. */
  12. @Value("${minio.end-point}")
  13. private String endpoint;
  14. /**
  15. * accessKey类似于用户ID,用于唯一标识你的账户
  16. */
  17. @Value("${minio.access-key}")
  18. private String accessKey;
  19. /**
  20. * secretKey是你账户的密码
  21. */
  22. @Value("${minio.secret-key}")
  23. private String secretKey;
  24. /**
  25. * 默认存储桶
  26. */
  27. @Value("${minio.bucket}")
  28. private String bucketName;
  29. @Bean
  30. public MinioClient minioClient() {
  31. MinioClient minioClient = MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();
  32. return minioClient;
  33. }
  34. }

三、使用postman进行测试

文件上传到minio

测试结果:

从minio中下载文件

 

直接下载即可,这样就完成了从minio中下载指定文件,还有部分接口,如果感兴趣的小伙伴可以自行测试看下实际效果。

        综上所有的代码就简单的介绍了一下Java实现文件上传和下载,希望能给你们实际开发带来一定的帮助,如果有出现问题的地方,希望指出,便于后续修改。

所有源码均以上传至https://download.csdn.net/download/m0_64210833/89233948

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/代码探险家/article/detail/865264
推荐阅读
相关标签
  

闽ICP备14008679号