阿里OSS实现图片上传,返回预览地址

注册阿里OSS

首先进入阿里云的官网:https://www.aliyun.com/

紧接着点击首页上的立即开通:

springboot中放置pdf文件供预览_spring


springboot中放置pdf文件供预览_上传_02


点击这个创建一个bucket

springboot中放置pdf文件供预览_API_03


springboot中放置pdf文件供预览_spring_04


springboot中放置pdf文件供预览_API_05

其余的默认就可以,可以根据自己的实际需求去写

使用代码操作阿里OSS

首先需要申请一个阿里颁发(id和秘钥)

在控制台的这里进入:

springboot中放置pdf文件供预览_spring boot_06


springboot中放置pdf文件供预览_spring boot_07


去创建一个AccessKey

springboot中放置pdf文件供预览_上传_08


创建完成之后就科一开始配置java了

Spring Boot 初始化OSS

阿里OSS开发文档地址:https://help.aliyun.com/document_detail/32008.html
首先在pom文件中添加依赖:

<!-- 阿里 oss 存储 -->
<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.10.2</version>
</dependency>

这个大家可以参考官方文档 JDK9以上需要添加别的依赖,我这里是JDK8

紧接着在application.yml中配置阿里OSS的秘钥

# 阿里云OSS
# 不同的服务器地址不同
aliyun:
  oss:
    file:
      endpoint: https://阿里云地址.com # 这里在申请完秘钥之后都会有
      keyid: # 秘钥值
      keysecret: # 秘钥偏移量
      bucketname: # 创建bucket的名字

配置完成之后编写配置类

package com.an.notepad.utils;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * OSS配置类
 *
 * @author An
 * @description TODO
 * @date 2022/6/22 1:06
 */
// 当项目启动,Spring 接口,Spring加载之后执行接口中的方法
@Component
public class ConstantPropertiesUtils implements InitializingBean {
    // 读取配置文件内容
    @Value("${aliyun.oss.file.endpoint}")
    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_POINT;
    public static String ACCESS_KEY_ID;
    public static String ACCESS_KEY_SECRET;
    public static String BUCKET_NAME;

    @Override
    public void afterPropertiesSet() throws Exception {
        END_POINT = endpoint;
        ACCESS_KEY_ID = keyId;
        ACCESS_KEY_SECRET = keySecret;
        BUCKET_NAME = bucketName;
    }

}

上传图片和删除图片的controller层

package com.an.notepad.controller;

import com.an.notepad.common.Result;
import com.an.notepad.service.OssService;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
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;

/**
 * @author An
 * @description TODO OSS 控制器 返回前端 JSON格式数据
 * @date 2022/6/22 1:24
 */
@RestController
@RequestMapping("/images")
@CrossOrigin
public class OssController {
    @Autowired
    private OssService ossService;

    @ApiOperation(value = "上传图片")
    @RequiresAuthentication
    @PostMapping("/upload")
    public Result uploadImages(MultipartFile file) {
        // 获取上传头像的文件 MultipartFile
        // 返回上传的oss路径
        String url = ossService.uploadImages(file);
        return Result.succ(url);
    }

    @ApiOperation(value = "删除图片")
    @RequiresAuthentication
    @PostMapping("/delete")
    public Result deleteImages(String fileUrl) {
        boolean flag = ossService.deleteImages(fileUrl);
        if (flag) {
            return Result.succ("删除成功", true);
        }
        return Result.fail("删除失败", false);
    }

}

下面是Service层:

package com.an.notepad.service;

import org.springframework.web.multipart.MultipartFile;

/**
 * @author An
 * @description TODO OSS service接口层
 * @date 2022/6/22 1:25
 */
public interface OssService {
    /**
     * 上传图片
     * @param file
     * @return
     */
    String uploadImages(MultipartFile file);

    /**
     * 删除图片
     * @param fileUrl
     * @return
     */
    boolean deleteImages(String fileUrl);
}

紧接着是实现层:(主要的核心逻辑就在这里面了,具体代码意思可以看注释)

package com.an.notepad.service.impl;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.ObjectMetadata;
import com.an.notepad.service.OssService;
import com.an.notepad.utils.ConstantPropertiesUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.util.Date;

/**
 * @author An
 * @description TODO OSS service接口实现层
 * @date 2022/6/22 1:26
 */
@Service
public class OssServiceImpl implements OssService {
    /**
     * 上传图片到oss
     *
     * @param file 图片文件
     * @return
     */
    @Override
    public String uploadImages(MultipartFile file) {
        // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
        String endpoint = ConstantPropertiesUtils.END_POINT;
        // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
        String accessKeyId = ConstantPropertiesUtils.ACCESS_KEY_ID;
        String accessKeySecret = ConstantPropertiesUtils.ACCESS_KEY_SECRET;
        // 填写Bucket名称,例如examplebucket。
        String bucketName = ConstantPropertiesUtils.BUCKET_NAME;

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        // 上传文件流
        try {
            // 获取文件的名称
            String fileName = file.getOriginalFilename();
            ObjectMetadata objectMetadata = new ObjectMetadata();
            objectMetadata.setContentType(getcontentType(fileName.substring(fileName.lastIndexOf("."))));
            // 调用oss的方法实现长传
            // 第一个参数 bucketName
            // 第二个参数 上传到oss的文件路径和文件名称
            ossClient.putObject(bucketName, fileName, new ByteArrayInputStream(file.getBytes()),objectMetadata);
            // 关闭OSSClient。
            ossClient.shutdown();
            // 把上传的文件路径返回 (手动拼接)
            // 这里设置图片有效时间 我设置了30年
            Date expiration = new Date(System.currentTimeMillis() + 946080000 * 1000);
            String url = ossClient.generatePresignedUrl(bucketName, fileName, expiration).toString();
            return url;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 删除图片
     *
     * @param fileUrl 图片路径
     * @return
     */
    @Override
    public boolean deleteImages(String fileUrl) {
        // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
        String endpoint = ConstantPropertiesUtils.END_POINT;
        // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
        String accessKeyId = ConstantPropertiesUtils.ACCESS_KEY_ID;
        String accessKeySecret = ConstantPropertiesUtils.ACCESS_KEY_SECRET;
        // 填写Bucket名称,例如examplebucket。
        String bucketName = ConstantPropertiesUtils.BUCKET_NAME;
        //创建OSSClient实例
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        String imgFile = fileUrl.replace("https://bucket-ans.oss-cn-hangzhou.aliyuncs.com/", "");
        String fileName = imgFile.substring(0, imgFile.indexOf("?"));

        // 根据BucketName,objectName删除文件
        ossClient.deleteObject(bucketName, fileName);
        ossClient.shutdown();
        return true;
    }
	// 实现图片的预览功能
    public static String getcontentType(String FilenameExtension) {
        if (FilenameExtension.equalsIgnoreCase(".bmp")) {
            return "image/bmp";
        }
        if (FilenameExtension.equalsIgnoreCase(".gif")) {
            return "image/gif";
        }
        if (FilenameExtension.equalsIgnoreCase(".jpeg") ||
                FilenameExtension.equalsIgnoreCase(".jpg") ||
                FilenameExtension.equalsIgnoreCase(".png")) {
            return "image/jpg";
        }
        if (FilenameExtension.equalsIgnoreCase(".html")) {
            return "text/html";
        }
        if (FilenameExtension.equalsIgnoreCase(".txt")) {
            return "text/plain";
        }
        if (FilenameExtension.equalsIgnoreCase(".vsd")) {
            return "application/vnd.visio";
        }
        if (FilenameExtension.equalsIgnoreCase(".pptx") ||
                FilenameExtension.equalsIgnoreCase(".ppt")) {
            return "application/vnd.ms-powerpoint";
        }
        if (FilenameExtension.equalsIgnoreCase(".docx") ||
                FilenameExtension.equalsIgnoreCase(".doc")) {
            return "application/msword";
        }
        if (FilenameExtension.equalsIgnoreCase(".xml")) {
            return "text/xml";
        }
        return "image/jpg";
    }

}

这样的话后端的接口就做好了

我这里项目集成了swagger2所以我用swagger接口文档进行测试:

springboot中放置pdf文件供预览_spring boot_09


springboot中放置pdf文件供预览_spring boot_10


预览成功

这种方式还是相对比较简单的。