当前位置:   article > 正文

SpringCloud微服务之使用阿里云对象存储OSS(笔记)_spring cloud oss

spring cloud oss

学会用阿里云对象存储OSS存放图片资源



前言

提示:这是一篇笔记,用来记录使用oss的操作步骤

例如:由于自己的笔记总是存放不周到,导致每次找笔记的时候都比写笔记还麻烦,所有索性现在养成一个习惯,将一些笔记记录在网上,这样不仅可以脱离空间限制,而且也好管理,这次的是微服务中OSS的使用。


提示:以下是本篇文章正文内容,下面案例可供参考

一、OSS是什么?

 OSS是阿里云对象存储服务(Object Storage Service)的一个简称,它是阿里云提供的海量、安全、低成本、高可靠的云存储服务。

二、使用步骤

1.创建一个文件上传的微服务

 1.1 创建upload-service项目,如下图

在这里插入图片描述

 1.2 导入依赖,代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <!--引入父项目-->
    <parent>
        <groupId>com.qs</groupId>
        <artifactId>music</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <groupId>com.qs</groupId>
    <artifactId>upload-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>upload-service</name>

    <description>upload-service</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <!--引入公共模块-->
        <dependency>
            <groupId>com.qs</groupId>
            <artifactId>commons-service</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

        <!--引入nacos客户端依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

  • 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
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
 1.3 在commons-service微服务导入oss依赖

commons-service微服务全部依赖如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.qs</groupId>
        <artifactId>music</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>


    <groupId>com.qs</groupId>
    <artifactId>commons-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>commons-service</name>
    <description>commons-service</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>


        <!--oss依赖-->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.9.1</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- 引入jwt加密-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>
        <!--加入时间工具类-->
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>2.9.9</version>
        </dependency>

        <!--        hutu工具包-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.2.5</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

  • 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
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
 1.4 在commons-service微服务下面的utils加入OssUtil,代码,图片如下:

在这里插入图片描述

OssUtil类的代码如下:

package com.qs.commonsservice.utlis;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.OSSObject;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Calendar;
import java.util.Date;

/**
 * @author zhx
 * @create 2022-12-2022-12-2816:54
 */
public class OssUtil {
//阿里oss的网址
    private static String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
    //accessKeyId  accessKeySecret 注册开通oss都会生成一个表格 直接填入
    private static String accessKeyId = 需自己填入;
   
    private static String accessKeySecret = 需自己填入;
    // bucketName 名
    private static String bucketName = 需自己填入;

    /**
     * 上传文件-文件夹拼接(a/b/c/+filename)(流的形式-ecs免流量)
     * @param inputStream 文件流
     * @param folder 文件夹
     * @param fileName 文件名字(保留后缀)
     * @return 保存的文件key
     */
    public static String uploadObjectByInputStream(InputStream inputStream, String folder, String fileName){
        OSS client = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        //folder+/+fileName
        String key;
        if(StringUtils.isEmpty(folder)){
            key = fileName;
        }else{
            key = folder + fileName;
        }
        try{
            client.putObject(bucketName, key, inputStream);
        }catch (Exception e){
            throw e;
        }finally {
            client.shutdown();
        }
        return key;
    }

    /**
     * 上传文件-全路径(a/b/c/filename)(流的形式-ecs免流量)
     * @param inputStream 文件流
     * @param fileFullPath 文件全路径(保留后缀)
     * @return 保存的文件key
     */
    public static String uploadObjectByInputStream(InputStream inputStream, String fileFullPath) throws Exception{
        OSS client = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        try{
            client.putObject(bucketName, fileFullPath, inputStream);
        }catch (Exception e){
            throw e;
        }finally {
            client.shutdown();
        }
        return fileFullPath;
    }

    /**
     * 通过oss->File->key值 获取对应文件的流(字节-网络传输)
     * @param fileKey
     * @return
     */
    public static byte[] getFileByteByKey(String fileKey) throws Exception {
        OSS client = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        InputStream inputStream = null;
        byte[] result = null;
        try {
            OSSObject ossObject = client.getObject(bucketName, fileKey);
            inputStream = ossObject.getObjectContent();
            result = toByteArray(inputStream);
        }catch (Exception e){
            throw e;
        }finally {
            try{
                if(inputStream!=null){
                    inputStream.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
            client.shutdown();
        }
        return result;
    }

    /**
     * 通过key值 获取对应文件的流(InputStream)
     * 实际上这个方法是无效的(client.shutdwon()会将流关闭 )
     * 所以可以这里进行流的操作 (比如可以参见:getFileByteByKey())
     * 把流读取到可以被保存的数据媒介中
     * @param fileKey
     * @return
     */
    @Deprecated
    public static InputStream getFileInputStreamByKey(String fileKey) {
        OSS client = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        InputStream inputStream = null;
        try {
            OSSObject ossObject = client.getObject(bucketName, fileKey);
            inputStream = ossObject.getObjectContent();
        }catch (Exception e){
            throw e;
        }finally {
            try{
                if(inputStream!=null){
                    inputStream.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
            client.shutdown();
        }
        return inputStream;
    }

    /**
     * 根据文件名获取文件访问URL(外网访问-下行收费)
     * @param ossFileKey 文件名
     * @param expires URL有效时间(小时)
     * @return
     */
    public static String getFileUrl(String ossFileKey, int expires) {
        OSS client = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        URL url = client.generatePresignedUrl(bucketName, ossFileKey, dateAfter(new Date(), expires, Calendar.HOUR));
        String path = url.toString();
        return path;
    }

    /**
     * 原图生成缩略图url
     * @param ossFileKey
     * @return
     */
    public static String getSltFileUrl(String ossFileKey,String centerName) throws IOException {
        OSS client = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        /**
         * 控制台设置的图片处理的style或者默认style
         */
        String style = "image/auto-orient,1/resize,m_lfit,w_100/quality,q_90";
        GetObjectRequest request = new GetObjectRequest(bucketName,ossFileKey);
        request.setProcess(style);
        OSSObject ossObject = client.getObject(request);
        InputStream inputStream = ossObject.getObjectContent();
        String suffix = ossFileKey.substring(ossFileKey.lastIndexOf("."));
        String name = ossFileKey.substring(0,ossFileKey.lastIndexOf("."));
        String sltName = name+centerName+suffix;
        System.out.println(sltName);
        try{
            client.putObject(bucketName, sltName, inputStream);
        }catch (Exception e){
            throw e;
        }finally {
            client.shutdown();
        }
        return sltName;
    }


    /**
     * (private)input转字节
     * @param input
     * @return
     * @throws Exception
     */
    private static byte[] toByteArray(InputStream input) throws Exception {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        byte[] buffer = new byte[4096];
        int n = 0;
        while (-1 != (n = input.read(buffer))) {
            output.write(buffer, 0, n);
        }
        return output.toByteArray();
    }

    /**
     * (private)获得指定日期之后一段时期的日期。例如某日期之后3天的日期等。
     * @param origDate 基准日期
     * @param amount 基准日期
     * @param timeUnit 时间单位,如年、月、日等。用Calendar中的常量代表
     * @return
     */
    private static final Date dateAfter(Date origDate, int amount, int timeUnit) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(origDate);
        calendar.add(timeUnit, amount);
        return calendar.getTime();
    }

}
  • 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
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
 1.5 配置upload-service微服务的配置文件

配置文件代码如下:

server:
  port: 8003

# 服务名及注解到远程nacos服务器
spring:
  application:
    name: upload-service
  cloud:
    nacos:
      discovery:
        group: dev
        namespace: (命名空间名字)
        server-addr: localhost:8848


  servlet:
    multipart:
      max-file-size: -1     # 无限制
      max-request-size: -1  #最大文件请求默认10m

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
 1.6 在upload-service微服务下面的创建控制层编写FileUploadController类

FileUploadController类代码如下:

package com.qs.uploadservice.controller;


import com.qs.commonsservice.utlis.OssUtil;
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 javax.annotation.Resource;
import java.io.IOException;

/**
 * @开发者 曾焓骁
 * @创建日期 2023-03-18 11:49
 * @开发版本 1.0
 */
@RestController
public class FileUploadController {

    //上传的地址我们要返回给vue前端,所以要定义
    //DIR为你的地址
    private String DIR = "";

    @PostMapping("/upload")
    public String upload(MultipartFile file) throws Exception {

        String filename = file.getOriginalFilename();//获取原始名字
        //将上传的文件 直接放到oss存储空间的根目录
        String newFileName = OssUtil.uploadObjectByInputStream(file.getInputStream(),filename);
        System.out.println("上传路径"+DIR+newFileName);
        return DIR+newFileName;
    }
}

  • 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
  • 36
 1.7 在gateway-service微服务的配置文件中配置

代码如下(因为是yml文件,注意缩进):

	gateway:
      routes:
      	- id: upload-service-id
          uri: lb://upload-service
          predicates:
          - Path=/api/upload
          filters:
          - StripPrefix=1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2.编写前端vue测试图片上传

测试代码如下:

		<!--编写默认隐藏的弹出界面-->
				<el-dialog :title="title" :visible.sync="dialogFormVisible">
					<el-form :model="music">				
						<el-form-item label="歌曲名称">
							<el-input type="text" v-model="music.name" auto-complete="off"></el-input>
						</el-form-item>
						<el-form-item label="歌曲图片" v-model="music.picUrl">
							<el-upload class="uploader" :show-file-list="imgFlag" :headers="headers"
							action="http://localhost:8888/api/upload" :on-success="handleAvatarSuccess">
								<img v-if="music.picUrl" :src="music.picUrl" height="80" width="100" class="avatar"/>  <!--有图片就显示图片-->
								<i v-else class="el-icon-plus avatar-uploader-icon"></i>  <!--没有显示加号-->
							</el-upload>
						</el-form-item>
					</el-form>
					<div slot="footer" class="dialog-footer">
						<el-button type="danger" @click="cancel()">取消</el-button>
						<el-button type="primary" @click="saveForm()">保存</el-button>
					</div>
				</el-dialog>
		
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

总结

记录从微服务中取出来的oss的过程和测试代码

 记录下使用OSS的操作步骤,以后当个cv自己的代码的超级战士

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

闽ICP备14008679号