当前位置:   article > 正文

SpringBoot通用模块--文件上传开发(阿里云OSS)

SpringBoot通用模块--文件上传开发(阿里云OSS)

文件上传,是指将本地图片、视频、音频等文件上传到服务器上,可以供其他用户浏览或下载的过程。文件上传在项目中应用非常广泛,我们经常发抖音、发朋友圈都用到了文件上传功能。

实现文件上传服务,需要有存储的支持,那么我们的解决方案将以下几种:

  1. 直接将图片保存到服务的硬盘(springmvc中的文件上传)

    1. 优点:开发便捷,成本低

    2. 缺点:扩容困难

  2. 使用分布式文件系统进行存储

    1. 优点:容易实现扩容

    2. 缺点:开发复杂度稍大(有成熟的产品可以使用,比如:FastDFS,MinIO)

  3. 使用第三方的存储服务(例如OSS)

    1. 优点:开发简单,拥有强大功能,免维护

    2. 缺点:付费

在本项目选用阿里云的OSS服务进行文件存储。

因为在新增菜品时,需要上传菜品对应的图片(文件),包括后绪其它功能也会使用到文件上传,故要实现通用的文件上传接口。

文件上传,是指将本地图片、视频、音频等文件上传到服务器上,可以供其他用户浏览或下载的过程。文件上传在项目中应用非常广泛,我们经常发抖音、发朋友圈都用到了文件上传功能。

实现文件上传服务,需要有存储的支持,那么我们的解决方案将以下几种:

  1. 直接将图片保存到服务的硬盘(springmvc中的文件上传)

    1. 优点:开发便捷,成本低

    2. 缺点:扩容困难

  2. 使用分布式文件系统进行存储

    1. 优点:容易实现扩容

    2. 缺点:开发复杂度稍大(有成熟的产品可以使用,比如:FastDFS,MinIO)

  3. 使用第三方的存储服务(例如OSS)

    1. 优点:开发简单,拥有强大功能,免维护

    2. 缺点:付费

在本项目选用阿里云的OSS服务进行文件存储。(前面课程已学习过阿里云OSS,不再赘述)

定义OSS相关配置

在sky-server模块

注意冒号后面有空格!!!

application-dev.yml(开发环境下的配置文件,yml可以引用该文件的值,这样就不用把值写死)

  1. sky:
  2. alioss:
  3.   endpoint: oss-cn-hangzhou.aliyuncs.com
  4.   access-key-id: LTAI5tPeFLzsPPT8gG3LPW64
  5.   access-key-secret: U6k1brOZ8gaOIXv3nXbulGTUzy6Pd7
  6.   bucket-name: sky-take-out

application.yml

  1. spring:
  2. profiles:
  3.   active: dev    #设置环境
  4. sky:
  5. alioss:
  6.   endpoint: ${sky.alioss.endpoint}
  7.   access-key-id: ${sky.alioss.access-key-id}
  8.   access-key-secret: ${sky.alioss.access-key-secret}
  9.   bucket-name: ${sky.alioss.bucket-name}

细节:application-dev.yml是开发环境下的配置文件,yml可以引用该文件的值,这样就不用把值写死

读取配置信息

封装一个类专门存放配置信息

在sky-common模块中,已定义配置属性类(读取配置文件中对应的配置信息sky.alioss,并将其封装为一个类)

@ConfigurationProperties(prefix = "sky.alioss")

 细节:

  • 配置类存放位置:common的properties包下
  • 配置类的注解:@Component
  • @ConfigurationProperties(prefix = "sky.alioss")说明配置类对应的配置项

 生成OSS工具类对象

在sky-server模块

定义一个配置类用于自动创建OSS工具类对象(在此过程中为配置类的属性赋值了)

  1. package com.sky.config;
  2. import com.sky.properties.AliOssProperties;
  3. import com.sky.utils.AliOssUtil;
  4. import lombok.extern.slf4j.Slf4j;
  5. import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
  6. import org.springframework.context.annotation.Bean;
  7. import org.springframework.context.annotation.Configuration;
  8. /**
  9. * 配置类,用于创建AliOssUtil对象
  10. */
  11. @Configuration
  12. @Slf4j
  13. public class OssConfiguration {
  14. //自动启动
  15. @Bean
  16. //工具类对象只需要存在一个bean就好
  17. @ConditionalOnMissingBean
  18. public AliOssUtil aliOssUtil(AliOssProperties aliOssProperties){
  19. log.info("开始创建阿里云文件上传工具类对象:{}",aliOssProperties);
  20. return new AliOssUtil(aliOssProperties.getEndpoint(),
  21. aliOssProperties.getAccessKeyId(),
  22. aliOssProperties.getAccessKeySecret(),
  23. aliOssProperties.getBucketName());
  24. }
  25. }

其中,AliOssUtil.java已在sky-common模块中定义

  1. package com.sky.utils;
  2. import com.aliyun.oss.ClientException;
  3. import com.aliyun.oss.OSS;
  4. import com.aliyun.oss.OSSClientBuilder;
  5. import com.aliyun.oss.OSSException;
  6. import lombok.AllArgsConstructor;
  7. import lombok.Data;
  8. import lombok.extern.slf4j.Slf4j;
  9. import java.io.ByteArrayInputStream;
  10. @Data
  11. @AllArgsConstructor
  12. @Slf4j
  13. public class AliOssUtil {
  14. private String endpoint;
  15. private String accessKeyId;
  16. private String accessKeySecret;
  17. private String bucketName;
  18. /**
  19. * 文件上传
  20. *
  21. * @param bytes
  22. * @param objectName
  23. * @return
  24. */
  25. public String upload(byte[] bytes, String objectName) {
  26. // 创建OSSClient实例。
  27. OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
  28. try {
  29. // 创建PutObject请求。
  30. ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(bytes));
  31. } catch (OSSException oe) {
  32. System.out.println("Caught an OSSException, which means your request made it to OSS, "
  33. + "but was rejected with an error response for some reason.");
  34. System.out.println("Error Message:" + oe.getErrorMessage());
  35. System.out.println("Error Code:" + oe.getErrorCode());
  36. System.out.println("Request ID:" + oe.getRequestId());
  37. System.out.println("Host ID:" + oe.getHostId());
  38. } catch (ClientException ce) {
  39. System.out.println("Caught an ClientException, which means the client encountered "
  40. + "a serious internal problem while trying to communicate with OSS, "
  41. + "such as not being able to access the network.");
  42. System.out.println("Error Message:" + ce.getMessage());
  43. } finally {
  44. if (ossClient != null) {
  45. ossClient.shutdown();
  46. }
  47. }
  48. //文件访问路径规则 https://BucketName.Endpoint/ObjectName
  49. StringBuilder stringBuilder = new StringBuilder("https://");
  50. stringBuilder
  51. .append(bucketName)
  52. .append(".")
  53. .append(endpoint)
  54. .append("/")
  55. .append(objectName);
  56. log.info("文件上传到:{}", stringBuilder.toString());
  57. return stringBuilder.toString();
  58. }
  59. }

注意: 

  1. //文件访问路径规则 https://BucketName.Endpoint/ObjectName
  2. StringBuilder stringBuilder = new StringBuilder("https://");
  3. stringBuilder
  4. .append(bucketName)
  5. .append(".")
  6. .append(endpoint)
  7. .append("/")
  8. .append(objectName);

定义文件上传通用接口

在sky-server模块中定义接口

  1. package com.sky.controller.admin;
  2. import com.sky.constant.MessageConstant;
  3. import com.sky.result.Result;
  4. import com.sky.utils.AliOssUtil;
  5. import io.swagger.annotations.Api;
  6. import io.swagger.annotations.ApiOperation;
  7. import lombok.extern.slf4j.Slf4j;
  8. import org.springframework.beans.factory.annotation.Autowired;
  9. import org.springframework.web.bind.annotation.PostMapping;
  10. import org.springframework.web.bind.annotation.RequestMapping;
  11. import org.springframework.web.bind.annotation.RestController;
  12. import org.springframework.web.multipart.MultipartFile;
  13. import java.io.IOException;
  14. import java.util.UUID;
  15. /**
  16. * 通用接口
  17. */
  18. @RestController
  19. @RequestMapping("/admin/common")
  20. @Api(tags = "通用接口")
  21. @Slf4j
  22. public class CommonController {
  23. @Autowired
  24. private AliOssUtil aliOssUtil;
  25. /**
  26. * 文件上传
  27. * @param file
  28. * @return
  29. */
  30. @PostMapping("/upload")
  31. @ApiOperation("文件上传")
  32. public Result<String> upload(MultipartFile file){
  33. log.info("文件上传:{}",file);
  34. try {
  35. //原始文件名
  36. String originalFilename = file.getOriginalFilename();
  37. //截取原始文件名的后缀 dfdfdf.png substring只传一个参数,表示从该位置开始截取
  38. String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
  39. //构造新文件名称
  40. String objectName = UUID.randomUUID().toString() + extension;
  41. //文件的请求路径
  42. String filePath = aliOssUtil.upload(file.getBytes(), objectName);
  43. return Result.success(filePath);
  44. } catch (IOException e) {
  45. log.error("文件上传失败:{}", e);
  46. }
  47. return Result.error(MessageConstant.UPLOAD_FAILED);
  48. }
  49. }

细节:

MultipartFile file这个file一定是和前端请求的文件名保持一致的,不能随便取名。

 

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

闽ICP备14008679号