3

SpringBoot integrates Alibaba Cloud OSS file upload, download, view, and delete

Basic Information

Involving knowledge points

  • Introduction to OSS and quick start to use Alibaba Cloud OSS console
  • SpringBoot integrates Alibaba Cloud OSS storage services to upload, download, view, and delete files
  • Introduction to Alibaba Cloud OSS documentation and quick start to use
  • Getting started with lombok and IDEA lombok plug-in installation
  • SpringMVC and AJAX front-end and back-end separation interaction
  • AJAX file upload asynchronously

Detailed project

Preparation before development

  • Development tool: IDEA
  • Basic environment: Maven + JDK8
  • Technology used: SpringBoot, lombok, Alibaba Cloud OSS storage service
  • SpringBoot version: 2.4.5

Use Alibaba Cloud OSS

1. Create a bucket

To use OSS, you first need to create a bucket. Bucket translates to Chinese and means a bucket. The stored image resources are regarded as water. If you want to hold water, you must have a bucket.
Enter the console, https://oss.console.aliyun.com/overview
image.png
Click Create Bucket
image.png
After the creation is complete, you can see the created bucket in the bucket list, and click to view the overview of the current bucket:
image.png

2. Manage files

File management can be done online
image.png

3. Alibaba Cloud OSS document

Alibaba Cloud provides more detailed development documents for users' reference:
image.png

Project initialization

Create SpringBoot project

image.png
image.png
image.png
image.png

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

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.4</version>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>joda-time</groupId>
    <artifactId>joda-time</artifactId>
    <version>2.9.9</version>
</dependency>

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.8.1</version>
</dependency>
IDEA install lombok plug-in (omitted)

Back-end service writing

Alibaba Cloud OSS configuration

Create a new application-oss.properties under resource

aliyun.endpoint=oss-cn-beijing.aliyuncs.com
aliyun.accessKeyId=LTAI5t9mpendCkALZKtBcqW1
aliyun.accessKeySecret=XXX(你的accessKeySecret)
aliyun.bucketName=malf-bucket
aliyun.urlPrefix=https://malf-bucket.oss-cn-beijing.aliyuncs.com/
spring.servlet.multipart.max-file-size=100MB
spring.servlet.multipart.max-request-size=1000MB

The endpoint, bucketName, and urlPrefix can be seen on the OSS overview page;
accessKeyId and accessKeySecret need to be checked in Access Key.

Configuration class code
package com.malf.config;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClient;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

/**
 * @author 巅峰小词典
 * @description
 * @date 2021/5/20
 * @project springboot_oss
 */
@Configuration
@PropertySource(value = {"classpath:application-oss.properties"})
@ConfigurationProperties(prefix = "aliyun")
@Data
public class AliyunConfig {

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

    @Bean
    public OSS oSSClient() {
        return new OSSClient(endpoint, accessKeyId, accessKeySecret);
    }
    
}
Back-end business code
common
package com.malf.common;

import lombok.Data;

/**
 * @author 巅峰小词典
 * @description 用于前后端交互的返回值
 * @date 2021/5/20
 * @project springboot_oss
 */
@Data
public class FileUploadResult {

    // 文件唯一标识
    private String uid;
    // 文件名
    private String name;
    // 状态有:uploading done error removed
    private String status;
    // 服务端响应内容,如:'{"status": "success"}'
    private String response;

}
service
package com.malf.service;

import com.aliyun.oss.OSS;
import com.aliyun.oss.model.ListObjectsRequest;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.OSSObjectSummary;
import com.aliyun.oss.model.ObjectListing;
import com.malf.common.FileUploadResult;
import com.malf.config.AliyunConfig;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.*;
import java.util.List;

/**
 * @author 巅峰小词典
 * @description 使用ossClient操作阿里云OSS,进行上传、下载、删除、查看所有文件等操作,同时可以将图片的url进行入库操作。
 * @date 2021/5/20
 * @project springboot_oss
 */
@Service
public class FileUploadService {

    // 允许上传的格式
    private static final String[] IMAGE_TYPE = new String[]{".bmp", ".jpg", ".jpeg", ".gif", ".png"};

    @Resource
    private OSS ossClient;
    @Resource
    private AliyunConfig aliyunConfig;

    /**
     * 文件上传
     *
     * @param uploadFile
     * @return
     */
    public FileUploadResult upload(MultipartFile uploadFile) {
        // 校验图片格式
        boolean isLegal = false;
        for (String type : IMAGE_TYPE) {
            if (StringUtils.endsWithIgnoreCase(uploadFile.getOriginalFilename(), type)) {
                isLegal = true;
                break;
            }
        }
        // 封装Result对象,并且将文件的byte数组放置到result对象中
        FileUploadResult fileUploadResult = new FileUploadResult();
        if (!isLegal) {
            fileUploadResult.setStatus("error");
            return fileUploadResult;
        }
        // 文件新路径
        String fileName = uploadFile.getOriginalFilename();
        String filePath = getFilePath(fileName);
        // 上传到阿里云
        try {
            ossClient.putObject(aliyunConfig.getBucketName(), filePath, new ByteArrayInputStream(uploadFile.getBytes()));
        } catch (Exception e) {
            e.printStackTrace();
            // 上传失败
            fileUploadResult.setStatus("error");
            return fileUploadResult;
        }
        fileUploadResult.setStatus("done");
        fileUploadResult.setResponse("success");
        // 文件路径需要保存到数据库
        fileUploadResult.setName(this.aliyunConfig.getUrlPrefix() + filePath);
        fileUploadResult.setUid(String.valueOf(System.currentTimeMillis()));
        return fileUploadResult;
    }

    /**
     * 生成路径以及文件名
     *
     * @param sourceFileName
     * @return
     */
    private String getFilePath(String sourceFileName) {
        DateTime dateTime = new DateTime();
        return "images/" + dateTime.toString("yyyy") + "/" + dateTime.toString("MM") + "/"
                + dateTime.toString("dd") + "/" + System.currentTimeMillis()
                + RandomUtils.nextInt(100, 9999) + "."
                + StringUtils.substringAfterLast(sourceFileName, ".");
    }

    /**
     * 查看文件列表
     *
     * @return
     */
    public List<OSSObjectSummary> list() {
        // 设置最大个数。
        final int maxKeys = 200;
        // 列举文件。
        ObjectListing objectListing = ossClient.listObjects(new ListObjectsRequest(aliyunConfig.getBucketName()).withMaxKeys(maxKeys));
        List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
        return sums;
    }

    /**
     * 删除文件
     *
     * @param objectName
     * @return
     */
    public FileUploadResult delete(String objectName) {
        // 根据BucketName,objectName删除文件
        ossClient.deleteObject(aliyunConfig.getBucketName(), objectName);
        FileUploadResult fileUploadResult = new FileUploadResult();
        fileUploadResult.setName(objectName);
        fileUploadResult.setStatus("removed");
        fileUploadResult.setResponse("success");
        return fileUploadResult;
    }

    /**
     * 下载文件
     *
     * @param os
     * @param objectName
     * @throws IOException
     */
    public void exportOssFile(OutputStream os, String objectName) throws IOException {
        // ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。
        OSSObject ossObject = ossClient.getObject(aliyunConfig.getBucketName(), objectName);
        // 读取文件内容。
        BufferedInputStream in = new BufferedInputStream(ossObject.getObjectContent());
        BufferedOutputStream out = new BufferedOutputStream(os);
        byte[] buffer = new byte[1024];
        int lenght = 0;
        while ((lenght = in.read(buffer)) != -1) {
            out.write(buffer, 0, lenght);
        }
        if (out != null) {
            out.flush();
            out.close();
        }
        if (in != null) {
            in.close();
        }
    }

}
controller
package com.malf.controller;

import com.aliyun.oss.model.OSSObjectSummary;
import com.malf.common.FileUploadResult;
import com.malf.service.FileUploadService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * @author 巅峰小词典
 * @description
 * @date 2021/5/20
 * @project springboot_oss
 */
@Controller
public class FileUploadController {

    @Resource
    private FileUploadService fileUploadService;

    @RequestMapping("file/upload")
    @ResponseBody
    public FileUploadResult upload(@RequestParam("file") MultipartFile uploadFile) throws Exception {
        return this.fileUploadService.upload(uploadFile);
    }

    @RequestMapping("file/delete")
    @ResponseBody
    public FileUploadResult delete(@RequestParam("fileName") String objectName) throws Exception {
        return this.fileUploadService.delete(objectName);
    }

    @RequestMapping("file/list")
    @ResponseBody
    public List<OSSObjectSummary> list() throws Exception {
        return this.fileUploadService.list();
    }

    @RequestMapping("file/download")
    @ResponseBody
    public void download(@RequestParam("fileName") String objectName, HttpServletResponse response) throws IOException {
        // 浏览器以附件形式下载
        response.setHeader("Content-Disposition", "attachment;filename=" + new String(objectName.getBytes(), "ISO-8859-1"));
        this.fileUploadService.exportOssFile(response.getOutputStream(), objectName);
    }

}
Front-end page writing and testing
File upload page upload.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>oss文件上传</title>
    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    <script>
        function uploadfile() {
            $("#fileTypeError").html('');
            // 获得文件名称
            var fileName = $('#file_upload').val();
            // 截取文件类型,如(.jpg)                
            var fileType = fileName.substr(fileName.length - 4, fileName.length);
            // 验证文件类型,此处验证也可使用正则
            if (fileType == '.bmp' || fileType == '.jpg' || fileType == '.jpeg' || fileType == '.gif' || fileType == '.png') {
                $.ajax({
                    url: 'file/upload',// 上传地址
                    type: 'POST',
                    cache: false,
                    data: new FormData($('#uploadForm')[0]),// 表单数据
                    processData: false,
                    contentType: false,
                    success: function (rtn) {
                        if (rtn.status == 'error') {
                            $("#fileTypeError").html('*上传文件类型错误,支持类型: .bmp .jpg .jpeg .gif .png'); // 根据后端返回值,回显错误信息
                        } else {
                            $('div').append('<img src="' + rtn.name + '" style="width: 300px;height: 300px"></img>')
                        }
                    }
                });
            } else {
                $("#fileTypeError").html('*上传文件类型错误,支持类型: .bmp .jpg .jpeg .gif .png');
            }
        }
    </script>
</head>
<body>
<form id="uploadForm" enctype="multipart/form-data">        <!-- 声明文件上传 -->
    <input id="file_upload" type="file" name="file"/>       <!-- 定义change事件,选择文件后触发 -->
    <br/><span style="color: red" id="fileTypeError"></span>    <!-- 文件类型错误回显,此处通过前后端两次验证文件类型 -->
    <br/><input type="button" onclick="uploadfile()" value="上传">
</form>
<div></div>
</body>
</html>

Show results:
image.png
image.png
image.png

File management page manager.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>oss文件管理</title>
    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    <script>
        var pre = 'https://malf-bucket.oss-cn-beijing.aliyuncs.com/';
        $(function () {
            listfile();
        });

        // 文件列表
        function listfile() {
            $.ajax({
                url: "http://localhost:8080/file/list",
                type: 'POST',
                success: function (rtn) {
                    console.log(rtn.length);
                    for (var i = 0; i < rtn.length; i++) {
                        $('div').append('<img src="' + pre + rtn[i].key + '" style="width: 300px;height: 300px; padding: 10px" ondblclick="deletefile(this.src)" onclick="downloadfile(this.src)"></img>')
                    }
                }
            });
        }

        // 文件下载
        function downloadfile(src) {
            var fileName = src.split(pre)[1];
            window.location.href = "http://localhost:8080/file/download?fileName=" + fileName;
        }

        // 文件删除
        function deletefile(src) {
            var fileName = src.split(pre)[1];
            var param = {fileName: fileName};
            $.ajax({
                url: "http://localhost:8080/file/delete",
                data: param,
                success: function () {
                    alert('删除成功', fileName);
                    // 删除页面
                    location.reload();
                }
            });
        }
    </script>
</head>
<body>
单击下载oss上的图片、双击删除oss上的图片<br>
<div>

</div>
</body>
</html>

Show results:
image.png
After the test is successful, SpringBoot integrates the basic framework of Alibaba Cloud OSS file upload, download, view, and deletion to build successfully.

Source code reference

springboot_oss


巅峰小词典
948 声望1.3k 粉丝

百无一用是书生,春鸟秋虫自做声。