• 使用阿里云OSS实现头像上传


    对象存储OSS
    1. 为了解决海量数据存储与弹性扩容,项目中采用云存储的解决方案 - 阿里云OSS

      (1)打开阿里云网站,注册账号,最好用支付宝注册,因为需要实名认证
      (2)使用注册的用户登录阿里云,充个几毛钱
      (3)找到阿里云OSS并开通
      (4)在OSS管理控制台创建bucket
      (5)创建操作阿里云oss许可证(阿里云颁发的id和密钥)
      
      • 1
      • 2
      • 3
      • 4
      • 5
    后端配置阿里云OSS
    1. 在父工程service模块下面创建子模块service_oss

      (1)选择maven类型
      (2)输入模块名称 service_oss
      
      • 1
      • 2
    2. 在service_oss中引入oss依赖

      (1)guli_parent/pom.xml中配置oss版本

      <properties>
          ...
          <aliyun.oss.version>2.8.3aliyun.oss.version>
          ...
      properties>
      
      • 1
      • 2
      • 3
      • 4
      • 5

      (2)service_oss/pom.xml中引入oss依赖

      <dependencies>
          
          <dependency>
              <groupId>com.aliyun.ossgroupId>
              <artifactId>aliyun-sdk-ossartifactId>
          dependency>
          <dependency>
              <groupId>com.aliyun.ossgroupId>
              <artifactId>aliyun-sdk-ossartifactId>
              <version>3.10.2version>
          dependency>
          ...
      dependencies>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
    3. 在service_oss/src/main/resources/中创建application.properties

      #服务端口
      server.port=8002
      #服务名
      spring.application.name=service-oss
      
      #环境设置:dev、test、prod
      spring.profiles.active=dev
      
      #阿里云 OSS
      #不同的服务器,地址不同
      #keyid和keysecret前面后面均不能加多余的空格
      aliyun.oss.file.endpoint=oss-cn-beijing.aliyuncs.com
      aliyun.oss.file.keyid=LTAI5t9AwGvbmLu41EPdPvQi
      aliyun.oss.file.keysecret=yC93McqdcpDgoRDlrGMeIw1aast8IY
      #bucket可以在控制台创建,也可以使用java代码创建
      aliyun.oss.file.bucketname=edu-jh
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
    4. 在service_oss/src/main/java中创建包com.atguigu.oss,在包中创建启动类OssApplication

      // 启动的时候,会去找数据库的配置,但是现在模块由于不需要操作数据库,只是做上传到oss功能,因此没有配置数据库
      @SpringBootApplication(exclude = DataSourceAutoConfiguration.class) // 在启动类添加exclude属性,默认不去加载数据库配置
      @ComponentScan(basePackages = {"com.atguigu"})
      public class OssApplication {
          public static void main(String[] args) {
              SpringApplication.run(OssApplication.class, args);
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    上传讲师头像后端接口
    1. 创建包com.atguigu.oss.utils,在包中创建常量类ConstantPropertiesUtils,读取配置文件内容

      @Component // 把该类交给spring管理
      public class ConstantPropertiesUtils implements InitializingBean { // 实现InitializingBean接口,spring加载之后,执行接口一个方法
          // 读取配置文件内容
          @Value("${aliyun.oss.file.endpoint}") // 配置文件key的名称(key-value)
          private String endpoint;
      
          @Value("${aliyun.oss.file.keyid}")
          private String keyId;
      
          @Value("${aliyun.oss.file.keysecret}")
          private String keySecret;
      
          @Value("${aliyun.oss.file.bucketname}")
          private String bucketName;
      
          // 为了别人可以使用,定义公开静态常量
          public static String END_POIND;
          public static String ACCESS_KEY_ID;
          public static String ACCESS_KEY_SECRET;
          public static String BUCKET_NAME;
      
          @Override
          public void afterPropertiesSet() throws Exception {
              END_POIND = endpoint;
              ACCESS_KEY_ID = keyId;
              ACCESS_KEY_SECRET = keySecret;
              BUCKET_NAME = bucketName;
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
    2. 在包com.atguigu.oss中写controller和service

      (1)创建包com.atguigu.oss.controller,在包中创建类OssController

          @RestController // 交给spring管理,返回json数据
          @RequestMapping("/eduoss/fileoss")
          @CrossOrigin // 解决跨域
          public class OssController {
              @Autowired
              private OssService ossService; // 注入service
      
              // 上传头像的方法
              @PostMapping
              public R uploadOssFile(MultipartFile file) {  // 获取上传文件
                  String url = ossService.uploadFileAvatar(file); // 返回上传到oss的路径
                  return R.ok().data("url",url);
              }
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14

      (2)创建包com.atguigu.oss.service,在包中创建接口OssService

          public interface OssService {
              String uploadFileAvatar(MultipartFile file);
          }
      
      • 1
      • 2
      • 3

      (3)创建包com.atguigu.oss.service.impl,在包中写接口OssService的实现类

          @Service
          public class OssServiceImpl implements OssService {
              @Override
              public String uploadFileAvatar(MultipartFile file) { // 上传头像到oss
                  // 工具类获取值
                  String endpoint = ConstantPropertiesUtils.END_POIND;
                  String accessKeyId = ConstantPropertiesUtils.ACCESS_KEY_ID;
                  String accessKeySecret = ConstantPropertiesUtils.ACCESS_KEY_SECRET;
                  String bucketName = ConstantPropertiesUtils.BUCKET_NAME;
      
                  try {
                      OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); // 创建OSS实例
                      InputStream inputStream = file.getInputStream(); // 获取上传文件输入流
                      String fileName = file.getOriginalFilename(); // 获取文件名称
      
                      // 在文件名称里面添加随机唯一的值
                      String uuid = UUID.randomUUID().toString().replaceAll("-","");
                      fileName = uuid+fileName; // yuy76t5rew01.jpg
      
                      // 把文件按照日期进行分类
                      String datePath = new DateTime().toString("yyyy/MM/dd"); // 获取当前日期
                      fileName = datePath+"/"+fileName; // 拼接
      
                      // 调用oss方法实现上传
                      ossClient.putObject(bucketName, fileName, inputStream);
                      ossClient.shutdown(); // 关闭OSSClient
      
                      // 把上传之后文件路径返回
                      return "https://"+bucketName+"."+endpoint+"/"+fileName;
                  } catch(Exception e) {
                      e.printStackTrace();
                      return null;
                  }
              }
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
    上传讲师头像前端实现
    1. 创建上传组件,实现上传(ajax默认不支持直接上传文件)

      在src/components中添加组件ImageCropper和PanThumb
      
      • 1
    2. 在views/edu/teacher/save.vue中,使用上传组件

      (1)属性

          v-show:是否显示上传组件
          :key:类似于id,如果一个页面多个图片上传控件,可以做区分
          :url:后台上传的url地址
          @close:关闭上传组件
          @crop-upload-success:上传成功后的回调
      
      • 1
      • 2
      • 3
      • 4
      • 5

      (2)代码

          
          <el-form-item label="讲师头像">
              <pan-thumb :image="teacher.avatar"/>
              <el-button type="primary" icon="el-icon-upload" @click="imagecropperShow=true">更换头像el-button>
              <image-cropper
                  v-show="imagecropperShow"
                  :width="300"
                  :height="300"
                  :key="imagecropperKey"
                  :url="BASE_API+'/eduoss/fileoss'"
                  field="file"
                  @close="close"
                  @crop-upload-success="cropSuccess"/>
          el-form-item>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
    3. 引入组件

      import ImageCropper from '@/components/ImageCropper'
      import PanThumb from '@/components/PanThumb'
      
      • 1
      • 2
    4. 声明组件和使用组件

      export default {
        components: { ImageCropper, PanThumb },  // 声明组件
        data() {
           return { // 使用组件
             ...
             imagecropperShow:false, // 上传弹框组件是否显示
             imagecropperKey:0, // 上传组件key值
             BASE_API:process.env.BASE_API, // 获取dev.env.js里面地址
             ...
           }
        },
        methods:{
          close() { // 关闭上传弹框的方法
              this.imagecropperShow = false
              this.imagecropperKey = this.imagecropperKey+1 // 上传组件初始化
          },
          cropSuccess(data) { // 上传成功方法
            this.imagecropperShow = false
            this.teacher.avatar = data.url // 上传之后接口返回图片地址
            this.imagecropperKey = this.imagecropperKey+1
          },
          ...
        }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
  • 相关阅读:
    java.util.ConcurrentModificationException: null(已解决)
    LeetCode LCP 57. 打地鼠 -- 动态规划+二分查询过滤无效数据
    Maven高级
    pytorch基础学习(4)
    文心一言 VS 讯飞星火 VS chatgpt (242)-- 算法导论17.4 1题
    从 DevOps 到平台工程:软件开发的新范式
    代码随想录 动态规划 判断子序列,不同的子序列
    HFS 快速搭建 http 服务器
    【matplotlib基础】--3D图形
    SPI通讯简介
  • 原文地址:https://blog.csdn.net/qq_41829337/article/details/126890479