Web项目利用OSS进行图像存储服务

一、OSS介绍        

        在Web项目中,一些常见的功能,比如展示图片,修改头像等,都需要进行图片的上传操作,但是如果是存储在Web服务器中,在读取图片的时候会占用比较多的资源,影响服务器的性能。

        常见的方式是使用OSS(Object Storage Service)存储图片或视频。

用户会先将图片上传至服务器,服务器这里担任的是中转的角色,前端界面发送请求到后端,后端需要保存数据(例如,图片的访问链接),返回给前端,后续需要浏览图片的时候,前端通过访问后端所返回的响应体中的链接到OSS中进行访问。

这种方式可以有效的节省服务器所需的资源,减轻带宽压力。

这里我们是使用七牛云OSS进行服务器直传(数据流的方式)的展示(有一定的免费存储空间),

详情可以参考操作文档:Java SDK_SDK 下载_对象存储 - 七牛开发者中心 (qiniu.com)

二、演示案例

2.1 引入Maven依赖

<dependency>
  <groupId>com.qiniu</groupId>
  <artifactId>qiniu-java-sdk</artifactId>
  <version>[7.13.0, 7.13.99]</version>
</dependency>

 2.2 默认提供的代码

        //构造一个带指定 Region 对象的配置类
        Configuration cfg = new Configuration(Region.region0());
        cfg.resumableUploadAPIVersion = Configuration.ResumableUploadAPIVersion.V2;// 指定分片上传版本
        //...其他参数参考类注释

        UploadManager uploadManager = new UploadManager(cfg);
        //...生成上传凭证,然后准备上传
        String accessKey = "your access key";
        String secretKey = "your secret key";
        String bucket = "your bucket name";

        //默认不指定key的情况下,以文件内容的hash值作为文件名
        String key = null;

        try {
            byte[] uploadBytes = "hello qiniu cloud".getBytes("utf-8");
            ByteArrayInputStream byteInputStream=new ByteArrayInputStream(uploadBytes);
            Auth auth = Auth.create(accessKey, secretKey);
            String upToken = auth.uploadToken(bucket);

            try {
                Response response = uploadManager.put(byteInputStream,key,upToken,null, null);
                //解析上传成功的结果
                DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
                System.out.println(putRet.key);
                System.out.println(putRet.hash);
            } catch (QiniuException ex) {
                ex.printStackTrace();
                if (ex.response != null) {
                    System.err.println(ex.response);

                    try {
                        String body = ex.response.toString();
                        System.err.println(body);
                    } catch (Exception ignored) {
                    }
                }
            }
        } catch (UnsupportedEncodingException ex) {
            //ignore
        }

这里我们可以先对代码进行简单的修改,使其实现我们的功能,之后我们再一步步的优化,

2.2.1 修改Region配置类

通过观察,我们需要修改Region对象的配置类:

文档:

 

这里我们设置为autoRegion,它会自动帮我们绑定我们在七牛云上创建的OSS仓库的地址。

2.2.2 AK,SK,bucket name的查看和修改 

显而易见,还需要修改密钥,即AK,SK,和 bucket name。

AK,SK,在密钥管理处查看:

密钥管理界面如下: 

修改的话,这边是利用 @ConfigurationProperties从配置文件中获取,需要注意的是,使用改注解的时候,还需要给这些属性,配置对应的set方法才行:

当然,你也可以使用@Value从配置文件中获取属性。

yml配置文件如下:

 

 2.2.3 修改存储到OSS的文件名,存储的文件

到此,其实就可以实现一个简单的文件上传了:

 

2.2.4 代码实现

package com.fox;

import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import org.junit.jupiter.api.Test;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;

@SpringBootTest
@ConfigurationProperties(prefix = "oss")
public class OSSTest {

    private String accessKey;
    private String secretKey;

    private String bucket;

    public void setAccessKey(String accessKey) {
        this.accessKey = accessKey;
    }

    public void setSecretKey(String secretKey) {
        this.secretKey = secretKey;
    }

    public void setBucket(String bucket) {
        this.bucket = bucket;
    }

    @Test
    public void testOss() {
        //构造一个带指定 Region 对象的配置类
        Configuration cfg = new Configuration(Region.autoRegion());
        cfg.resumableUploadAPIVersion = Configuration.ResumableUploadAPIVersion.V2;// 指定分片上传版本
        //...其他参数参考类注释

        UploadManager uploadManager = new UploadManager(cfg);
        //...生成上传凭证,然后准备上传

        //默认不指定key的情况下,以文件内容的hash值作为文件名
        String key = "2022/fox.jpg";

        try {
//            byte[] uploadBytes = "hello qiniu cloud".getBytes("utf-8");
//            ByteArrayInputStream byteInputStream=new ByteArrayInputStream(uploadBytes);
            InputStream inputStream = new FileInputStream("C:\\Users\\86136\\Desktop\\Snipaste_2024-02-03_17-30-29.png");
            Auth auth = Auth.create(accessKey, secretKey);
            String upToken = auth.uploadToken(bucket);

            try {
                Response response = uploadManager.put(inputStream,key,upToken,null, null);
                //解析上传成功的结果
                DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
                System.out.println(putRet.key);
                System.out.println(putRet.hash);
            } catch (QiniuException ex) {
                ex.printStackTrace();
                if (ex.response != null) {
                    System.err.println(ex.response);

                    try {
                        String body = ex.response.toString();
                        System.err.println(body);
                    } catch (Exception ignored) {
                    }
                }
            }
        } catch (Exception ex) {
            //ignore
        }

    }
}

三、实际项目中的OSS案例

其实跟上述过程差不多,只是将一些写死的数据,演变为可变的,并且返回响应给前端工程即可:

3.1 改进1:利用Lombok注解代替set方法

3.2 改进2:利用工具类动态生成文件名称

接受图片方法如下,该方法会返回给前端访问该图片的链接,ResponseResult为我自己定义的统一格式响应体。

    @Override
    public ResponseResult uploadImg(MultipartFile img) {
        //获取原始文件名
        String originalFilename = img.getOriginalFilename();
        //对原始文件名进行判断
        if (!originalFilename.endsWith(".png") && !originalFilename.endsWith(".jpg")) {
            throw new SystemException(AppHttpCodeEnum.FILE_TYPE_ERROR);
        }
        //如果判断通过那么就上传文件到OSS
        String filePath = PathUtils.generateFilePath(originalFilename);
        String url = uploadOss(img,filePath);

        return ResponseResult.okResult(url);
    }

PathUtils工具类如下,用于动态生成文件名:

package com.fox.utils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

public class PathUtils {

    public static String generateFilePath(String fileName){
        //根据日期生成路径   2022/1/15/
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/");
        String datePath = sdf.format(new Date());
        //uuid作为文件名
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        //后缀和文件后缀一致
        int index = fileName.lastIndexOf(".");
        // test.jpg -> .jpg
        String fileType = fileName.substring(index);
        return new StringBuilder().append(datePath).append(uuid).append(fileType).toString();
    }
}

以下为uploadOss方法,key即为文件名,我们需要返回给前端的url,就是外链访问路径加上文件名即可:

bucket绑定的域名(外链访问域名获取)如下: 

3.3 总结:

代码实现:

package com.fox.service.impl;

import com.fox.domain.ResponseResult;
import com.fox.enums.AppHttpCodeEnum;
import com.fox.exception.SystemException;
import com.fox.service.UploadService;
import com.fox.utils.PathUtils;
import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;

@Service
@Data
@ConfigurationProperties(prefix = "oss")
public class OssUploadServiceImpl implements UploadService {

    private String accessKey;
    private String secretKey;
    private String bucket;

    @Override
    public ResponseResult uploadImg(MultipartFile img) {
        //获取原始文件名
        String originalFilename = img.getOriginalFilename();
        //对原始文件名进行判断
        if (!originalFilename.endsWith(".png") && !originalFilename.endsWith(".jpg")) {
            throw new SystemException(AppHttpCodeEnum.FILE_TYPE_ERROR);
        }
        //如果判断通过那么就上传文件到OSS
        String filePath = PathUtils.generateFilePath(originalFilename);
        String url = uploadOss(img,filePath);

        return ResponseResult.okResult(url);
    }
    private String uploadOss(MultipartFile imgFile, String filePath) {
        //构造一个带指定 Region 对象的配置类
        Configuration cfg = new Configuration(Region.autoRegion());
        cfg.resumableUploadAPIVersion = Configuration.ResumableUploadAPIVersion.V2;// 指定分片上传版本
        //...其他参数参考类注释

        UploadManager uploadManager = new UploadManager(cfg);
        //...生成上传凭证,然后准备上传

        //默认不指定key的情况下,以文件内容的hash值作为文件名
        String key = filePath;

        try {
//            byte[] uploadBytes = "hello qiniu cloud".getBytes("utf-8");
//            ByteArrayInputStream byteInputStream=new ByteArrayInputStream(uploadBytes);
            InputStream inputStream = imgFile.getInputStream();
            Auth auth = Auth.create(accessKey, secretKey);
            String upToken = auth.uploadToken(bucket);

            try {
                Response response = uploadManager.put(inputStream,key,upToken,null, null);
                //解析上传成功的结果
                DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
                System.out.println(putRet.key);
                System.out.println(putRet.hash);
                return "图片外链除去文件名的url地址"+key;
            } catch (QiniuException ex) {
                ex.printStackTrace();
                if (ex.response != null) {
                    System.err.println(ex.response);

                    try {
                        String body = ex.response.toString();
                        System.err.println(body);
                    } catch (Exception ignored) {
                    }
                }
            }
        } catch (Exception ex) {
            //ignore
        }
        return "2";
    }

}

  • 22
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用Spring Boot和阿里云的OSS(对象存储服务)来存储图片。以下是实现步骤: 1. 集成OSS SDK 首先,需要在pom.xml文件中添加OSS SDK依赖: ``` <dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>2.9.2</version> </dependency> ``` 2. 配置OSS连接信息 在application.properties文件中添加OSS的连接信息: ``` oss.endpoint=your_endpoint oss.accessKeyId=your_access_key_id oss.accessKeySecret=your_access_key_secret oss.bucketName=your_bucket_name ``` 3. 创建OSS客户端 在代码中创建OSS客户端: ``` @Configuration public class OSSConfig { @Autowired private Environment env; @Bean public OSSClient ossClient() { String endpoint = env.getProperty("oss.endpoint"); String accessKeyId = env.getProperty("oss.accessKeyId"); String accessKeySecret = env.getProperty("oss.accessKeySecret"); return new OSSClient(endpoint, accessKeyId, accessKeySecret); } } ``` 4. 上传图片 在代码中使用OSS客户端上传图片: ``` @Service public class ImageService { @Autowired private OSSClient ossClient; public String uploadImage(MultipartFile file) throws IOException { String bucketName = env.getProperty("oss.bucketName"); String fileName = file.getOriginalFilename(); InputStream inputStream = file.getInputStream(); ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentType(file.getContentType()); metadata.setContentLength(file.getSize()); ossClient.putObject(bucketName, fileName, inputStream, metadata); return fileName; } } ``` 这里使用MultipartFile对象来接收上传的图片,然后将其转换为InputStream,使用OSSClient的putObject方法上传到OSS中,返回上传后的文件名。 以上就是利用Spring BootOSS存储图片的步骤,希望对你有帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值