使用阿里云的oss对象存储服务实现图片上传(前端vue后端java详解)

news2024/11/16 2:22:09

一:前期准备:

1.1:注册阿里云账号,开启对象存储oss功能,创建一个bucket(百度教程多的是,跟着创建一个就行,创建时注意存储类型是标准存储,读写权限是公共读)

二:后端设置:

2.1:引入依赖:

<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.10.2</version>
</dependency>

2.2:在application.yml中配置一些必要的属性,并写一个类读取出来(我是这样使用的,将某些特定的数据都写到application.yml文件中,方便更改,当然你也可以直接将他写在类的代码中,只不过找起来可能麻烦点)

bookstore:
  alioss:
    endpoint: xxxxx #外网访问的地域节点
    access-key-id: xxxxxx #访问阿里云api的秘钥
    access-key-secret: xxxxxxx #访问阿里云api的秘钥
    bucket-name: xxxxxxxx #bucket-name

//写在application.yml文件中,这些数据在阿里云中可以找到,秘钥在自己的账号主页里创建生成,地域节点和bucket-name都在创建好bucket后查看

读取配置中的数据 

package com.bookstore.common.properties;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "bookstore.alioss")
@Data
public class AliOssProperties {

    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    private String bucketName;

}

//读取配置里的相关数据

2.3:封装一个上传图片的工具类,阿里云已经给出了具体代码,没有什么需要修改的内容,直接cv大法就行

package com.bookstore.common.utils;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayInputStream;

@Data
@AllArgsConstructor
@Slf4j
public class AliOssUtil {

    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    private String bucketName;

    /**
     * 文件上传
     *
     * @param bytes
     * @param objectName
     * @return
     */
    public String upload(byte[] bytes, String objectName) {

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            // 创建PutObject请求。
            ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(bytes));
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }

        //文件访问路径规则 https://BucketName.Endpoint/ObjectName
        StringBuilder stringBuilder = new StringBuilder("https://");
        stringBuilder
                .append(bucketName)
                .append(".")
                .append(endpoint)
                .append("/")
                .append(objectName);

        log.info("文件上传到:{}", stringBuilder.toString());

        return stringBuilder.toString();
    }
}

2.4:写配置类,这个类是来创建AliOssUtil对象并注入到springboot中,就是实例化我们上面封装的那个工具类并将我们上面写的从配置中读取数据的类传进去,最后返回URL路径,它也没有什么需要更改的,cv就行

package com.bookstore.config;


import com.bookstore.common.properties.AliOssProperties;
import com.bookstore.common.utils.AliOssUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 配置类,用于创建AliOssUtil对象
 */
@Configuration
@Slf4j
public class OssConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public AliOssUtil aliOssUtil(AliOssProperties aliOssProperties){
        log.info("开始创建阿里云文件上传工具类对象:{}",aliOssProperties);
        return new AliOssUtil(aliOssProperties.getEndpoint(),
                aliOssProperties.getAccessKeyId(),
                aliOssProperties.getAccessKeySecret(),
                aliOssProperties.getBucketName());
    }
}

2.5:写一个通用接口,后端上传图片调的就是这个接口,上传一个图片,最后返回文件路径

package com.bookstore.controller.admin;

import com.bookstore.common.constant.MessageConstant;
import com.bookstore.common.result.Result;
import com.bookstore.common.utils.AliOssUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.UUID;

/**
 * 通用接口
 */
@RestController
@RequestMapping("/admin/common")
@Api(tags = "通用接口")
@Slf4j
public class CommonController {

    @Autowired
    private AliOssUtil aliOssUtil;

    /**
     * 文件上传
     * @param file
     * @return
     */
    @PostMapping("/upload")
    @ApiOperation("文件上传")
    public Result<String> upload(MultipartFile file){
        log.info("文件上传:{}",file);

        try {
            //原始文件名
            String originalFilename = file.getOriginalFilename();
            //截取原始文件名的后缀.png .jpg
            String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            //构造新文件名称
            String objectName = UUID.randomUUID().toString() + extension;

            //文件的请求路径
            String filePath = aliOssUtil.upload(file.getBytes(), objectName);
            return Result.success(filePath);
        } catch (IOException e) {
            log.error("文件上传失败:{}",e);
        }

        return Result.error(MessageConstant.UPLOAD_FAILED);
    }
}

 三:前端怎么写:

前端我使用的是vue框架,代码如下

3.1:模板组件:

<el-form-item label="图片" prop="image">
          <el-upload
            class="upload-demo"
            action="http://localhost:8082/admin/common/upload"
            method="post"
            :headers="{
              token: token,
            }"
            :on-success="handleUploadSuccess"
            :show-file-list="false"
            list-type="picture-card"
          >
            <img
              v-if="previewImage"
              :src="previewImage"
              style="width: 100%; height: 100%"
            />
            <i class="el-icon-plus avatar-uploader-icon" v-else></i>
          </el-upload>
        </el-form-item>
3.1.1:代码解释: 

 action:这里写的是我们上面的那个通用接口路径

method:使用post(后端就是使用的post方法)

:headers:这里用来设置请求头,我在请求头上添加了一个token用来校验用户

:on-success:这里是上传成功的回调函数

:show-file-list:设置是否显示文件列表

list-type="picture-card":设置上传文件列表的样式为图片卡片形式。图片卡片形式可以让用户更直观地看到上传的图片,并且可以方便地进行删除或替换操作。

下面的img组件和i标签组件我使用了v-if和v-else来显示上传成功后的样子(是上传之前的图标还是上传成功后的图片回显)

3.2:script的data里写:

data(){
    return{
        token: "",  //请求头
        previewImage: "", // 图片回显
    }
}

 3.3:script的方法中写好图片上传成功后的回调函数

handleUploadSuccess(response) {
      // 图片上传成功后的回调函数
      console.log(response.data);
      this.previewImage = response.data; // 设置图片回显
    },

四:运行效果:

4.1:上传图片之前:

4.2:上传图片后: 

4.3:后端控制台打印消息提示:

可以看到,运行成功,一切正常,而且我们的bucket里也是正常有图片的

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1411486.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习(6)---Transformer

文章目录 一、介绍二、架构2.1 Multi-head Attention2.2 Encoder(编码器)2.3 Decoder(解码器) 三、Encoder和Decoder之间的传递四、Training五、其他介绍5.1 Copy Mechanism5.2 Beam Search 一、介绍 1. Transformer是一个Seq2Seq&#xff08;Sequence-to-Sequence&#xff09;…

redis + 拦截器 :防止数据重复提交

1.项目用到,不是核心 我们干系统开发,不免要考虑一个点&#xff0c;数据的重复提交。 我想我们之前如果要校验数据重复提交要求&#xff0c;会怎么干?会在业务层&#xff0c;对数据库操作&#xff0c;查询数据是否存在,存在就禁止插入数据; 但是吧,我们每次crud操作都会连接…

【史上最全之 ChatGPT 和文心一言对比】

ChatGPT 和文心一言哪个更好用&#xff1f; 在当今的AI助手领域中&#xff0c;ChatGPT与文心一言无疑是备受瞩目的两位选手。两者分别由美国OpenAI公司和中国百度研发&#xff0c;均致力于提供卓越的人工智能对话体验。接下来&#xff0c;我们将从智能回复、语言准确性以及知识…

SQL - 事务控制

SQL - 事务控制 文章目录 SQL - 事务控制TCL - 事务事务的边界事务的特性事务的应用 事务隔离等级MySQL支持四种隔离级别 TCL - 事务 **模拟场景&#xff1a;**生活当中转账是转账方账户扣钱&#xff0c;收账方账户加钱。用数据库操作来模拟现实转账。 数据库模拟&#xff1a…

HH44X-16微阻缓闭式止回阀常见的问题

HH44X-16微阻缓闭式止回阀常见的问题 HH44X-16微阻缓闭式止回阀常遇问题包括以下几点&#xff1a; 一、泄漏&#xff1a; HH44X-16微阻缓闭式止回阀在关闭时可能会发生泄漏&#xff0c;导致介质倒流。泄漏可能由于密封失效、阀门磨损或堵塞等原因造成。 二、堵塞&#xff1a;…

复盘_用工具提升效率

流量池 从 2017 年 10 月&#xff0c;我开始写公众号&#xff0c;一直以来都是零零散散地写&#xff0c;读者也只是随随便便地看。而今年在连续日更了 10 天后&#xff0c;我获得了今年的第一次流量池推荐。 尽管和别人动辄十万百万的阅读量没法比。但是&#xff0c;考虑到我的…

echarts 绘制垂直滚动热力图

问题1&#xff1a;提示功能无效 问题2&#xff1a;值筛选无效 效果 在线浏览 下载echarts官网例子(heatmap Examples - Apache ECharts) 稍作改动&#xff1a; generateData 入参改为长度和宽度noise.perlin2(i / 40, j / 20) Math.random() * 5y轴倒置指定zlevel为2 通过定…

如何使用Jellyfin+cpolar搭建私人影音平台实现无公网ip远程访问

文章目录 1. 前言2. Jellyfin服务网站搭建2.1. Jellyfin下载和安装2.2. Jellyfin网页测试 3.本地网页发布3.1 cpolar的安装和注册3.2 Cpolar云端设置3.3 Cpolar本地设置 4.公网访问测试5. 结语 1. 前言 随着移动智能设备的普及&#xff0c;各种各样的使用需求也被开发出来&…

2024年广东省安全员A证第四批(主要负责人)证模拟考试题库及广东省安全员A证第四批(主要负责人)理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年广东省安全员A证第四批&#xff08;主要负责人&#xff09;证模拟考试题库及广东省安全员A证第四批&#xff08;主要负责人&#xff09;理论考试试题是由安全生产模拟考试一点通提供&#xff0c;广东省安全员A证…

HCIE之BGP路由策略(三)

BGP 一、路由控制工具ACLIP-PREFIXRoute-Policy 二、BGP路由控制通过更改MED属性调节选路通过更改Local_Pref属性调节选路理解ACL、IP-PREFIX和Route-Policy中permit、deny的含义 三、BGP属性特点-团体属性练习no-advertise属性ORF 一、路由控制工具 在对BGP进行路由控制之前&…

你认识哪几种树结构

二叉树&#xff0c;B&#xff0c;B&#xff0c;B*&#xff0c;R树 二叉树 使用二分结构存储数据&#xff0c;查找数据时&#xff0c;耗时最好可达到O(log2N)。但是二叉树没有平衡的特性&#xff0c;所以在经过一系列的增删后&#xff0c;可能会出现极端的情况&#xff0c;耗时…

利用Python实现中文文本关键词抽取的三种方法

文本关键词抽取&#xff0c;是对文本信息进行高度凝练的一种有效手段&#xff0c;通过3-5个词语准确概括文本的主题&#xff0c;帮助读者快速理解文本信息。目前&#xff0c;用于文本关键词提取的主要方法有四种&#xff1a;基于TF-IDF的关键词抽取、基于TextRank的关键词抽取、…

代理模式-C#实现

该实例基于WPF实现&#xff0c;直接上代码&#xff0c;下面为三层架构的代码。 目录 一 Model 二 View 三 ViewModel 一 Model using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace 设计模式练…

像搭乐高一样把模型拼在一起

琳琅满目的乐高积木&#xff0c;通过一块又一块的叠加&#xff0c;可以创造出各种栩栩如生的人物、景观等&#xff0c;不同的乐高作品相互组合&#xff0c;又能为爱好者带来新的创意。 我们把思路打开一点&#xff0c;在大模型&#xff08;LLM&#xff09;爆发的当下&#xff0…

SpringBlade微服务开发平台

采用前后端分离的模式&#xff0c;前端开源两个框架&#xff1a;Sword (基于 React、Ant Design)、Saber (基于 Vue、Element-UI)后端采用SpringCloud全家桶&#xff0c;并同时对其基础组件做了高度的封装&#xff0c;单独开源出一个框架&#xff1a;BladeToolBladeTool已推送至…

Nginx部署、Jenkins自动发布、搜索服务概述、ES部署与使用、消息队列概述、RabbitMQ部署及使用

案例1&#xff1a;HIS前端代码测试 Fontend主机部署Nginx #HIS前端代码为编译后代码&#xff0c;可直接部署在nginx上查看效果[rootFontend ~]# yum clean all; yum repolist -vTotal packages: 8,265[rootFontend ~]# yum -y install nginx.x86_64 #安装nginx…

第13章_泛型(集合中使用泛型,比较器中使用泛型,自定义泛型结构,泛型在继承上的体现,通配符的使用)

文章目录 第13章_泛型(Generic)本章专题与脉络1. 泛型概述1.1 生活中的例子1.2 泛型的引入 2. 使用泛型举例2.1 集合中使用泛型2.1.1 举例2.1.2 练习 2.2 比较器中使用泛型2.2.1 举例2.2.2 练习 2.3 相关使用说明 3. 自定义泛型结构3.1 泛型的基础说明3.2 自定义泛型类或泛型接…

[git] windows系统安装git教程和配置

一、何为Git Git(读音为/gɪt/)是一个开源的分布式版本控制系统&#xff0c;可以有效、高速地处理从很小到非常大的项目版本管理。 二、git安装包 有2种版本&#xff0c;Git for Windows Setup和Git for Windows Portable(便携版)两个版本都可以。 三、Git for Windows Por…

【GPU】深入理解GPU硬件架构及运行机制

深入理解GPU硬件架构及运行机制 作者&#xff1a;Tim在路上​ 曾看到有一篇名为《The evolution of a GPU: from gaming to computing》的文章。 这篇文章非常热烈的讨论了这些年GPU的进步&#xff0c;这引发了我们的一些思考: 为什么我们总说GPU比CPU要强大&#xff0c;既然…

ISCTF2023 RE FloweyRSA WP

64位无壳&#xff0c;但是进去连main函数都没有 这里应该是main的头部 这里是一个jmp的花指令 jnz short labela 跳转到labela是一段没用的代码 所以把它和labela全部NOP 往下翻&#xff0c;又是必然跳转至label1 把jz short label1到db 0的花指令全部NOP label3这里也是类似的…