文档说明

此文档为拉钩Java高薪训练营2期课程学习过程,完成作业的文档。顺便说一句拉钩的课程,整个课程,体系非常全,价格上也是所有培训课程中最便宜的。如果希望构建一个整体的技术视野,非常推荐。

作业要求

使用SpringBoot和OSS实现图片的上传、下载和删除功能, 具体要求如下

  • 可以使用postman 发送上传请求 /oss/upload ,实现图片上传到OSS对应的Bucket中
    类型检查:必须为 jpg、png 或者 jpeg类型,其它图片类型返回错误提示信息
    大小检查:必须小于5M,大于5M时返回错误提示信息
    图片名称:生成的文件名,必须保持唯一
  • 可以使用postman 发送下载请求 /oss/download,实现图片下载
    可以根据图片名进行文件的下载
  • 可以使用postman 发送删除请求/oss/delete,实现图片删除
    可以根据图片名进行文件的删除

——————————————————————————————————
1、提供资料:说明文档,验证及讲解视频。
2、讲解内容包含:题目分析、实现思路、环境介绍。
—————————————————————————————————-

新建Bucke

image.png

项目搭建

aliyun.properties

  1. # aliyun.properties
  2. aliyun.endpoint=http://oss-cn-beijing.aliyuncs.com
  3. aliyun.accessKeyId=LTAI4GHJMokRfeEjNbyhdfGQ
  4. aliyun.accessKeySecret=DLjzBiTF1Eb6X7mZdOFBCzCQ6lROkI
  5. aliyun.bucketName=lg-mtest
  6. aliyun.urlPrefix=https://lg-mtest.oss-cn-beijing.aliyuncs.com/

application.properties

  1. server.port=8080
  2. # tomcat 默认上传文件大小不能超过 1M
  3. spring.servlet.multipart.max-file-size=10MB
  4. spring.servlet.multipart.max-request-size=20MB

添加依赖

  1. <dependency>
  2. <groupId>com.aliyun.oss</groupId>
  3. <artifactId>aliyun-sdk-oss</artifactId>
  4. <version>2.8.3</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.apache.commons</groupId>
  8. <artifactId>commons-lang3</artifactId>
  9. <version>3.7</version>
  10. </dependency>
  11. <!-- 时间处理工具包 -->
  12. <dependency>
  13. <groupId>joda-time</groupId>
  14. <artifactId>joda-time</artifactId>
  15. <version>2.9.9</version>
  16. </dependency>

AliyunConfig

  1. @Configuration
  2. // 加载配置文件
  3. @PropertySource("classpath:aliyun.properties")
  4. @ConfigurationProperties(prefix = "aliyun")
  5. public class AliyunConfig {
  6. private String endpoint;
  7. private String accessKeyId;
  8. private String accessKeySecret;
  9. private String bucketName;
  10. private String urlPrefix;
  11. // 生成OSSClient
  12. @Bean
  13. public OSSClient ossClient(){
  14. return new OSSClient(endpoint,accessKeyId,accessKeySecret);
  15. }
  16. // 省略 get set 方法
  17. }

UploadResult

  1. package com.example.demo.bean;
  2. public class UploadResult {
  3. // 文件唯一标识
  4. private String uid;
  5. // 文件名
  6. private String name;
  7. // 状态有:uploading done error removed
  8. private String status;
  9. // 服务端响应内容,如:'{"status": "success"}'
  10. private String response;
  11. }

FileService

  1. package com.example.demo.service;
  2. import com.aliyun.oss.OSSClient;
  3. import com.aliyun.oss.model.OSSObject;
  4. import com.aliyun.oss.model.ObjectMetadata;
  5. import com.example.demo.config.AliyunConfig;
  6. import org.apache.commons.lang3.StringUtils;
  7. import org.joda.time.DateTime;
  8. import org.springframework.beans.factory.annotation.Autowired;
  9. import org.springframework.stereotype.Service;
  10. import org.springframework.web.multipart.MultipartFile;
  11. import com.example.demo.bean.UploadResult;
  12. import javax.servlet.ServletOutputStream;
  13. import javax.servlet.http.HttpServletResponse;
  14. import java.io.ByteArrayInputStream;
  15. import java.io.IOException;
  16. import java.io.InputStream;
  17. import java.util.*;
  18. @Service
  19. public class FileService {
  20. @Autowired
  21. private AliyunConfig aliyunConfig;
  22. @Autowired
  23. private OSSClient ossClient;
  24. // 允许上传的格式
  25. private static final Set<String> IMAGE_TYPE = new HashSet<>(Arrays.asList(".jpg", ".jpeg", ".png"));
  26. /**
  27. * 文件上传
  28. * @param multipartFile
  29. * @return
  30. */
  31. public UploadResult upload(MultipartFile multipartFile) {
  32. UploadResult upLoadResult = new UploadResult();
  33. String fileName = multipartFile.getOriginalFilename();
  34. // 校验图片格式
  35. String fileType = fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
  36. if (!IMAGE_TYPE.contains(fileType)) {
  37. upLoadResult.setStatus("error");
  38. upLoadResult.setResponse("illegal media type");
  39. return upLoadResult;
  40. }
  41. // 校验文件大小, 超过 5M 为非法文件
  42. if (multipartFile.getSize()> 5 * 1024 * 1024) {
  43. upLoadResult.setStatus("error");
  44. upLoadResult.setResponse("file too large, file size must below 5M");
  45. return upLoadResult;
  46. }
  47. String filePath = getFilePath(fileName);
  48. try {
  49. ObjectMetadata metadata = new ObjectMetadata();
  50. metadata.addUserMetadata("originName", fileName);
  51. ossClient.putObject(aliyunConfig.getBucketName(), filePath, new ByteArrayInputStream(multipartFile.getBytes()), metadata);
  52. } catch (IOException e) {
  53. e.printStackTrace();
  54. // 上传失败
  55. upLoadResult.setStatus("error");
  56. upLoadResult.setResponse("file upload fail, some thing may be wrong");
  57. return upLoadResult;
  58. }
  59. upLoadResult.setStatus("done");
  60. upLoadResult.setName(aliyunConfig.getUrlPrefix() + filePath);
  61. upLoadResult.setUid(filePath);
  62. return upLoadResult;
  63. }
  64. /**
  65. * 文件下载
  66. * @param url
  67. * @param response
  68. */
  69. public boolean download(String url, HttpServletResponse response) {
  70. OSSObject object = ossClient.getObject(aliyunConfig.getBucketName(), url);
  71. byte[] buf = new byte[1024];
  72. int len;
  73. try(InputStream in = object.getObjectContent(); ServletOutputStream out = response.getOutputStream()) {
  74. while ((len = in.read(buf)) > 0) {
  75. out.write(buf, 0, len);
  76. }
  77. } catch (IOException e) {
  78. e.printStackTrace();
  79. return false;
  80. }
  81. return true;
  82. }
  83. /**
  84. * 删除文件
  85. * @param url
  86. * @return
  87. */
  88. public boolean delete(String url) {
  89. ossClient.deleteObject(aliyunConfig.getBucketName(), url);
  90. return true;
  91. }
  92. // 生成不重复的文件路径和文件名
  93. private String getFilePath(String sourceFileName) {
  94. DateTime dateTime = new DateTime();
  95. return "images/" + dateTime.toString("yyyy")
  96. + "/" + dateTime.toString("MM") + "/"
  97. + dateTime.toString("dd") + "/" + UUID.randomUUID().toString() + "." +
  98. StringUtils.substringAfterLast(sourceFileName, ".");
  99. }
  100. }

FileController

  1. package com.example.demo.controller;
  2. import com.example.demo.bean.UploadResult;
  3. import com.example.demo.service.FileService;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.stereotype.Controller;
  6. import org.springframework.web.bind.annotation.PostMapping;
  7. import org.springframework.web.bind.annotation.RequestMapping;
  8. import org.springframework.web.bind.annotation.RequestParam;
  9. import org.springframework.web.bind.annotation.ResponseBody;
  10. import org.springframework.web.multipart.MultipartFile;
  11. import javax.servlet.http.HttpServletResponse;
  12. @Controller
  13. @RequestMapping("/oss")
  14. public class FileController {
  15. @Autowired
  16. private FileService fileService;
  17. @PostMapping("/upload")
  18. @ResponseBody
  19. public UploadResult upload(@RequestParam("file") MultipartFile multipartFile) {
  20. return fileService.upload(multipartFile);
  21. }
  22. @RequestMapping("/download")
  23. @ResponseBody
  24. public String download(String url, HttpServletResponse response) {
  25. boolean download = false;
  26. try {
  27. download = fileService.download(url, response);
  28. } catch (Exception e) {
  29. e.printStackTrace();
  30. }
  31. if (download) {
  32. return "download success";
  33. }
  34. return "download failed";
  35. }
  36. @RequestMapping("/delete")
  37. @ResponseBody
  38. public String delete(String url) {
  39. boolean download = fileService.delete(url);
  40. if (download) {
  41. return "delete success";
  42. }
  43. return "delete failed";
  44. }
  45. }

测试

Postman 上传文件

image.png
image.png

Postman 下载文件

image.png

Postman 删除文件

image.png

异常情况测试

上传非法多媒体文件

image.png

上传大文件

image.png